1.前言
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
为了解决上述的问题,我们又使用了一种新的设计模式:工厂方法模式。
3.实例概况
- 背景:小成有一间塑料加工厂(仅生产A类产品);随着客户需求的变化,客户需要生产B类产品;
- 冲突:改变原有塑料加工厂的配置和变化非常困难,假设下一次客户需要再发生变化,再次改变将增大非常大的成本;
- 解决方案:小成决定置办塑料分厂B来生产B类产品;
使用步骤
步骤1: 创建抽象工厂类,定义具体工厂的公共接口
1 abstract class Factory{ 2 public abstract Product Manufacture(); 3 }
步骤2: 创建抽象产品类 ,定义具体产品的公共接口;
1 abstract class Product{ 2 public abstract void Show(); 3 }
步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;
1 //具体产品A类 2 class ProductA extends Product{ 3 @Override 4 public void Show() { 5 System.out.println("生产出了产品A"); 6 } 7 }
1 //具体产品B类 2 class ProductB extends Product{ 3 4 @Override 5 public void Show() { 6 System.out.println("生产出了产品B"); 7 } 8 }
步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
1 //工厂A类 - 生产A类产品 2 class FactoryA extends Factory{ 3 @Override 4 public Product Manufacture() { 5 return new ProductA(); 6 } 7 }
1 //工厂B类 - 生产B类产品 2 class FactoryB extends Factory{ 3 @Override 4 public Product Manufacture() { 5 return new ProductB(); 6 } 7 }
步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例
1 //生产工作流程 2 public class FactoryPattern { 3 public static void main(String[] args){ 4 //客户要产品A 5 FactoryA mFactoryA = new FactoryA(); 6 mFactoryA.Manufacture().Show(); 7 8 //客户要产品B 9 FactoryB mFactoryB = new FactoryB(); 10 mFactoryB.Manufacture().Show(); 11 } 12 }
结果:
生产出了产品A
生产出了产品C
4. 优点
- 更符合开-闭原则
新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
- 符合单一职责原则
每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
- 不使用静态工厂方法,可以形成基于继承的等级结构。
简单工厂模式的工厂类使用静态工厂方法
总结:工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
5. 缺点
- 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类,系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
- 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
- 一个具体工厂只能创建一种具体产品