初识设计模式之简单工厂模式、工厂方法模式、抽象工厂模式

  • 简单工厂模式

  • 工厂方法模式

  • 抽象工厂模式

​ 工厂顾名思义就是生产产品的意思,根据产品是具体产品还是具体工厂可分为简单工厂模式和工厂方法模式,根据工厂的抽象程度可分为工厂方法模式和抽象工厂模式。该模式用于封装和管理对象的创建,是一种创建型模式。

1. 简单工厂模式

​ 首先,我们有一个服装制造厂,有一张服装设计原稿。现在,我们需要根据各个经销商的要求制造出不同颜色的衣服。

  • Clothes接口:即服装设计原稿

    public interface Clothes {
      void getName();
    }
    
  • BlueClothes类:根据图纸制造出来的蓝色的衣服

    public class BlueClothes implements Clothes{
      public void getName() {
          System.out.print("BlueClothes");
      }
    }
    
  • RedClothes类:根据图纸制造出来的蓝色的衣服

    public class RedClothes implements Clothes{
      public void getName() {
          System.out.print("RedClothes");
      }
    }
    
  • GreenClothes类:根据图纸制造出来的蓝色的衣服

    public class GreenClothes implements Clothes{
      public void getName() {
          System.out.print("GreenClothes");
      }
    }
    
  • SimpleClothesFactory类:一个简单的服装制造厂

    public class SimpleClothesFactory {
        public Clothes CreateClothes(String orderColor) {
               Clothes Clothes = null;
               if (orderColor.equals("blue")) {
                      Clothes = new BlueClothes();
               } else if (orderColor.equals("red")) {
                      Clothes = new RedClothes();
               } else if (orderColor.equals("green")) {
                      Clothes = new GreenClothes();
               }
               return Clothes;
        }
        //开工开工
        public static void main(String[] args) {
          SimpleClothesFactory scf = new SimpleClothesFactory();
          scf.CreateClothes("red").getName();
            //拿到红色的订单后,输出"RedClothes"
        }
    }
    
    

    简单工厂模式的优点:

    • 工厂类是整个模式的关键。包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象。通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的。明确了各自的职责和权利,有利于整个软件体系结构的优化。

    简单工厂模式的缺点:

    • 由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
    • 当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求。这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利。
    • 这些缺点在工厂方法模式中得到了一定的克服。

    可以考虑的应用场景:

    • 工厂类负责创建的对象比较少;
    • 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
    • 由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

2. 工厂方法模式

​ 那么问题来了,在我们使用简单工厂模式时,当我们的服装厂生意做大了,吸引了无数经销商前来订单,这时我们厂里只能生产红、绿、蓝颜色的衣服。如果我们想要接下这批订单,那我们就要对原工厂进行改造,那就会消耗大量的人力物力了。这时,工厂方法模式就登场了!

  • Clothes接口:服装设计原稿

  • YellowClothes类:按稿件设计出来的黄色衣服

  • WhiteClothes类:按稿件设计出来的白色衣服

  • ClothesFactory接口:服装厂原型,建造具体服装厂时的标准

  • YellowClothesFactory类:生产黄色衣服的工厂

  • WhiteClothesFactory类:生产白色衣服的工厂

  • Work类:工厂开工(启动类)

    interface Clothes{
        void showTag();
    }
    
    class YellowClothes implements Clothes{
      public void showTag() {
          System.out.println("YellowClothes");
      }
    }
    
    class WhiteClothes implements Clothes{
      public void showTag() {
          System.out.println("WhiteClothes");
      }
    }
    
    interface ClothesFactory{
        public abstract Clothes produce();
    }
    
    class YellowClothesFactory implements ClothesFactory{
      public Clothes produce() {
          return new YellowClothes();
      }
    }
    
    class WhiteClothesFactory implements ClothesFactory{
      public Clothes produce() {
          return new WhiteClothes();
      }
    }
    
    public class Work {
      public static void main(String[] args){
          ClothesFactory ycf = new YellowClothesFactory();
          ycf.produce().showTag();
          //输出YellowClothes
          ClothesFactory wcf = new WhiteClothesFactory();
            wcf.produce().showTag();
            //输出WhiteClothes
        }
    }
    

​ 如此这般,在我们接受到新订单时我们只需要新建一个小工厂就可以了。不需要对建好的工厂进行改造。它能更好的符合开闭原则的要求。

工厂方法模式的优点:

  • 用户只需要关心产品对应的工厂,甚至无需关心创建细节或具体产品类的类名。
  • 基于工厂角色和产品的多态性设计是工厂模式的关键。它能自主决定如何创建哪种产品对象,而创建细节都封装在具体工厂内部。
  • 在系统要添加新的产品时,无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他的具体工厂和具体产品,只要添加一个具体工厂和具体产品即可,从而提高系统的可扩展性(符合开闭原则)

工厂方法模式的缺点:

  • 在添加新产品时,要编写新的具体产品类,并要提供与之对应的具体工厂类。系统软件个数也成对增加,从而增加了系统的复杂度,带来更多开销。
  • 由于系统的可扩展性,在客户端中要引入抽象层进行定义,从而增加了系统的抽象性和理解难度。

3. 抽象工厂模式

​ 工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。

让我们回到我们的服装厂继续分析,现在,我们已经不满足于衣服业务啦,我们要进军裤子生产届,那么问题来了,我们只有衣服生产厂,怎么办呢?我们现在迫切需要一种多个产品族结构的解决方案。

  • Clothes接口:衣服设计原稿

  • YellowClothes类:按稿件设计出来的黄色衣服

  • WhiteClothes类:按稿件设计出来的白色衣服

  • Trousers接口:裤子设计原稿

  • YellowTrousers类:按稿件设计出来的黄色裤子

  • WhiteTrousers类:按稿件设计出来的白色裤子

  • AbstractFactory抽象类:服装厂原型,建造具体服装厂时的标准

  • YellowFactory类:拥有黄色原料的工厂

  • WhiteFactory类:拥有白色原料的工厂

  • Work类:工厂开工(启动类)

    //衣服原稿
    interface Clothes{
        void showClothesTag();
    }
    //裤子原稿
    interface Trousers{
      void showTrousersTag();
    }
    
    //衣服原稿制作出来的黄色衣服
    class YellowClothes implements Clothes{
      public void showClothesTag() {
          System.out.println("YellowClothes");
      }
    }
    //衣服原稿制作出来的白色衣服
    class WhiteClothes implements Clothes{
      public void showClothesTag() {
          System.out.println("WhiteClothes");
      }
    }
    
    //衣服原稿制作出来的黄色裤子
    class YellowTrousers implements Trousers{
      public void showTrousersTag() {
          System.out.println("YellowTrousers");
      }
    }
    //衣服原稿制作出来的白色裤子
    class WhiteTrousers implements Trousers{
      public void showTrousersTag() {
          System.out.println("WhiteTrousers");
      }
    }
    
    //能生产衣服和裤子的工厂
    abstract class AbstractFactory{
      public abstract Clothes produceClothes();   
      public abstract Trousers produceTrousers();      
    }
    
    //拥有黄色原料的工厂
    class YellowFactory extends AbstractFactory{    
      public Clothes produceClothes() {        
          return new YellowClothes();    
      }    
      public Trousers produceTrousers() {        
          return new YellowTrousers();    
      }
    }
    //拥有白色原料的工厂
    class WhiteFactory extends AbstractFactory{    
      public Clothes produceClothes() {        
          return new WhiteClothes();    
      }    
      public Trousers produceTrousers() {        
          return new WhiteTrousers();    
      }
    }
    
    //启动类
    public class Work {
      public static void main(String[] args) {
          AbstractFactory yf = new YellowFactory();
          AbstractFactory wf = new WhiteFactory();
          System.out.println("黄色原料工厂正在生产:");
          yf.produceClothes().showClothesTag();
          yf.produceTrousers().showTrousersTag();
          System.out.println("白色原料工厂正在生产:");
          wf.produceClothes().showClothesTag();
          wf.produceTrousers().showTrousersTag();
      }
    }
    

    如此这般,我们就可以正式进军裤子制造届啦。

    抽象工厂模式的优点:

    • 分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。
    • 易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。
    • 有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。

    抽象工厂模式的缺点:

    • 难以支持新种类的产品。因为抽象工厂接口确定了可以被创建的产品集合,所以难以扩展抽象工厂以生产新种类的产品。

    可以考虑使用的场景:

    • 一个系统要独立于它的产品的创建、组合和表示时。
    • 一个系统要由多个产品系列中的一个来配置时。
    • 需要强调一系列相关的产品对象的设计以便进行联合使用时。
    • 提供一个产品类库,而只想显示它们的接口而不是实现时。

以上就是我对这三个模式的简单认识啦,也是作为个人的学习总结,仅供参考!

如有错误,万望指正。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容