zoukankan      html  css  js  c++  java
  • 工厂模式

    需要生成的对象叫做产品 ,生成对象的地方叫做工厂 。

    1.简单(静态)工厂模式

    产品的抽象类:

    1 public abstract class INoodles {
    2     /**
    3      * 描述每种面条啥样的
    4      */
    5     public abstract void desc();
    6 }
    View Code

    具体的产品类:

    1 public class LzNoodles extends INoodles {
    2     @Override
    3     public void desc() {
    4         System.out.println("兰州拉面 上海的好贵 家里才5 6块钱一碗");
    5     }
    6 }
    View Code

    具体的产品类:

    1 public class PaoNoodles extends INoodles {
    2     @Override
    3     public void desc() {
    4         System.out.println("泡面好吃 可不要贪杯");
    5     }
    6 }
    View Code

    简单工厂类:

     1 public class SimpleNoodlesFactory {
     2     public static final int TYPE_LZ = 1;//兰州拉面
     3     public static final int TYPE_PM = 2;//泡面
     4 
     5     public static INoodles createNoodles(int type) {
     6         switch (type) {
     7             case TYPE_LZ:
     8                 return new LzNoodles();
     9             case TYPE_PM:
    10                 return new PaoNoodles();
    11         }
    12     }
    13 }
    View Code

    客户使用简单工厂得到具体的产品类:

    1 /**
    2  * 简单工厂模式
    3  */
    4  INoodles noodles = SimpleNoodlesFactory.createNoodles(SimpleNoodlesFactory.TYPE_LZ);
    5  noodles.desc();
    View Code

    特点

    1 它是一个具体的类,非接口 抽象类。有一个重要的create()方法,利用if或者 switch创建产品并返回。

    2 create()方法通常是静态的,所以也称之为静态工厂。

    缺点

    1 扩展性差(我想增加一种面条,除了新增一个面条产品类,还需要修改工厂类方法)

    2 不同的产品需要不同额外参数的时候 不支持。

    另一种常用的简单工厂实现:

    简单工厂类:

     1 public class MulWayNoodlesFactory {
     2 
     3     /**
     4      * 模仿Executors 类
     5      * 生产泡面
     6      *
     7      * @return
     8      */
     9     public static INoodles createPm() {
    10         return new PaoNoodles();
    11     }
    12 
    13     /**
    14      * 模仿Executors 类
    15      * 生产兰州拉面
    16      *
    17      * @return
    18      */
    19     public static INoodles createLz() {
    20         return new LzNoodles();
    21     }
    22 }
    View Code

    客户类:

    1 INoodles lz2 = MulWayNoodlesFactory.createLz();
    2         lz2.desc();
    View Code

    2.工厂方法模式
    通工厂就是把简单工厂中具体的工厂类,划分成两层:抽象工厂层+具体的工厂子类层。(一般->特殊)

    抽象工厂类:

    1 public abstract class NoodlesFactory {
    2     public abstract INoodles create();
    3 }
    View Code

    针对产品的具体工厂类:

    1 public class LzFactory extends NoodlesFactory {
    2     @Override
    3     public INoodles create() {
    4         return new LzNoodles();
    5     }
    6 }
    View Code

    针对产品的具体工厂类:

    1 public class PaoFactory extends NoodlesFactory {
    2     @Override
    3     public INoodles create() {
    4         return new PaoNoodles();
    5     }
    6 }
    View Code

    客户使用抽象工厂的具体工厂类得到所需的产品:

    1 /**
    2          * 普通工厂方法:
    3          */
    4        
    5         NoodlesFactory factory = new LzFactory();
    6         INoodles lz = factory.create();
    7         lz.desc();
    View Code

    普通工厂与简单工厂模式的区别:

    可以看出,普通工厂模式特点:不仅仅做出来的产品要抽象, 工厂也应该需要抽象。

    工厂方法使一个产品类的实例化延迟到其具体工厂子类.

    工厂方法的好处就是更拥抱变化。当需求变化,只需要增删相应的类,不需要修改已有的类。

    而简单工厂需要修改工厂类的create()方法,多方法静态工厂模式需要增加一个静态方法。

    缺点:

    引入抽象工厂层后,每次新增一个具体产品类,也要同时新增一个具体工厂类,所以我更青睐 多方法静态工厂。

    3.抽象工厂模式

    以上介绍的工厂都是单产品系的。抽象工厂是多产品系 (貌似也有产品家族的说法)。

    举个例子来说,每个店(工厂)不仅仅卖面条,还提供饮料卖。 
    提供饮料卖,饮料是产品,先抽象一个产品类,饮料:

    新的抽象产品类:

    1 public abstract class IDrinks {
    2     /**
    3      * 描述每种饮料多少钱
    4      */
    5     public abstract void prices();
    6 }
    View Code

    具体的新的产品类:

    1 public class ColaDrinks extends IDrinks {
    2     @Override
    3     public void prices() {
    4         System.out.println("可乐三块五");
    5     }
    6 }
    View Code

    具体的新的产品类:

    1 public class WaterDrinks extends IDrinks {
    2     @Override
    3     public void prices() {
    4         System.out.println("和我一样的穷鬼都喝水,不要钱~!");
    5     }
    6 }
    View Code

    抽象工厂,既可以生产面条,也可以卖饮料:

     1 public abstract class AbstractFoodFactory {
     2     /**
     3      * 生产面条
     4      *
     5      * @return
     6      */
     7     public abstract INoodles createNoodles();
     8 
     9     /**
    10      * 生产饮料
    11      */
    12     public abstract IDrinks createDrinks();
    13 }
    View Code

    具体工厂类:

     1 public class LzlmFoodFactory extends AbstractFoodFactory {
     2     @Override
     3     public INoodles createNoodles() {
     4         return new LzNoodles();//卖兰州拉面
     5     }
     6 
     7     @Override
     8     public IDrinks createDrinks() {
     9         return new WaterDrinks();//卖水
    10     }
    11 }
    View Code

    具体工厂类:

     1 public class KFCFoodFactory extends AbstractFoodFactory {
     2     @Override
     3     public INoodles createNoodles() {
     4         return new PaoNoodles();//KFC居然卖泡面
     5     }
     6 
     7     @Override
     8     public IDrinks createDrinks() {
     9         return new ColaDrinks();//卖可乐
    10     }
    11 }
    View Code

    客户使用抽象工厂的具体工厂得到多种产品:

    1 AbstractFoodFactory abstractFoodFactory1 = new KFCFoodFactory();
    2         abstractFoodFactory1.createDrinks().prices();
    3         abstractFoodFactory1.createNoodles().desc();
    4 
    5         abstractFoodFactory1= new LzlmFoodFactory();
    6         abstractFoodFactory1.createDrinks().prices();
    7         abstractFoodFactory1.createNoodles().desc();
    View Code

    小结:

    将工厂也抽象了,在使用时,工厂和产品都是面向接口编程,OO(面向对象)的不得了。

    缺点

    但是将工厂也抽象后,有个显著问题,就是类爆炸了。而且每次拓展新产品种类,例如不仅卖吃卖喝,我还想卖睡,提供床位服务,这需要修改抽象工厂类,因此所有的具体工厂子类,都被牵连,需要同步被修改。

  • 相关阅读:
    密码由6-12位数字或字母组成,密码哈希加密
    获得一个字符串的汉语拼音码
    WPF中ComboBox绑定数据库自动读取产生数据
    SQL存储过程生成顺序编码
    SQL 语句调用这个存储过程,生成顺序编码
    restful(1):序列化
    Django的CBV和FBV
    权限管理组件:rbac
    ModelForm组件和forms组件补充
    BBS+Blog项目代码
  • 原文地址:https://www.cnblogs.com/cing/p/9176962.html
Copyright © 2011-2022 走看看