工厂模式

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

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(面向对象)的不得了。

缺点

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

原文地址:https://www.cnblogs.com/cing/p/9176962.html