学习笔记-设计模式-创建型模式-工厂模式
工厂模式
工厂模式是一种创建者设计模式,细分之下可以分成三类简单工厂模式
,工厂方法模式
和抽象工厂模式
。
简单工厂模式
最简单的工厂模式,它采用静态方法的方式来决定应该应该生产什么商品。
public class StoreFactory {
public static ICommodity getCommodityService(Integer commodityType) {
if (null == commodityType) {
return null;
}
switch (commodityType) {
case 1:
return new CouponCommodityService();
case 2:
return new GoodsCommodityService();
case 3:
return new CardCommodityService();
}
throw new RuntimeException("不存在的商品服务类型");
}
}
它的优点在于
- 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦
- 把初始化实例时的工作放到工厂里进行,使代码更容易维护,更符合面向对象的原则
面向接口编程,而不是面向实现编程
它的缺点在于
- 工厂类集中了所有实例的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响
- 违背
开闭原则
,一旦添加新的产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂 - 简单工厂模式使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构
它适用于
- 客户只知道传入工厂类的参数,对于如何创建对象的逻辑不关心时;
- 当工厂类负责创建的对象比较少时。
工厂方法模式
工厂方法模式
中,工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
它把类的实例化延迟到工厂类的子类中,由子类来决定应该实例化哪个类。
由此,它解决了简单工厂模式违背了开闭原则
的问题。
它的优点在于
- 更符合
开闭原则
- 符合
单一责任原则
,每个具体工厂类只负责创建对应的产品 - 不使用静态工厂方法,可以形成基于继承的等级结构
它的缺点在于
- 需要的类的数量非常多,每添加一个新产品,就要相应的添加一个新的工厂。
- 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另一种产品,仍然需要修改实例化的具体工厂类
- 一个工厂只能创建一种具体产品
它适用于:
- 当一个类不需要知道它所需要的对象的类时
- 当一个类希望通过其子类来指定创建对象时
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂的类名存储在配置文件或数据库中(比如spring中的FactoryBean)
抽象工厂模式
抽象工厂模式
定义了一个能生产一个产品族
的超级抽象工厂,然后交给子类工厂去生产某一个产品族
的产品。
产品族和产品等级
产品等级结构
既是产品的继承结构。比如一个抽象类是电视机,其子类有海尔电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构。
产品族
是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔生产的海尔电视机、海尔洗衣机和海尔冰箱,构成了一个产品族。
设计模式详解
图中,IProductFactory
是工厂接口,定义了生产手机和路由器组成的产品族的方法。而子类工厂HuaweiFactory
负责生产华为产品族,XiaomiFactory
负责生产小米产品族。
另外,IPhoneProduct
和IRouterProduct
分别定义了手机和路由器两个产品等级。
它的优点在于
- 一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
- 可以很方便地添加一个新的产品族
它的缺点在于
- 产品族的拓展非常困难,要增加一个系列的某一个产品,既要修改工厂抽象类里添加代码,又要在具体的实现类里面添加代码
- 增加了系统的抽象性和理解难度
它适用于
- 一系列相关产品对象(属于同一产品族)一起创建时需要大量的重复代码
- 提供一个产品类的库,所有的产品以同样的接口出现,从而使得客户端不依赖于具体的实现