工厂(简单工厂、工厂方法、抽象工厂)
简单工厂(静态工厂)
创建对象,而不向客户端暴露实例化细节
示例
- BeanFactory#getBean(): IMeituanSmsService
 - Integer#valueOf()
 - Proxy#newProxyInstance()
 - CommonResponse#buildSuccess()
 - java.sql.DriverManager#getDriver()
 - CreateOrderServiceFactory#getCreateOrderService()
 - AllItemsPriceCheckLogic#createErrorResult()
 
优点
- 分离创建对象的职责与对象本身所承担的职责,收敛创建对象的职责到工厂类。
 - 可读性强,有名字,根据方法的意图来命名。Lists#newArrayList() Lists#newLinkedList()
 - 对象可复用,(享元模式) Integer#valueOf(), Boolean#valueOf()
 - 创建参数化实例时,代码更简洁 Maps#newHashMap()
 - 可以返回更抽象的类型
 - 低耦合,将创建对象的职责和使用对象的职责中分开,客户端不需要知道具体的产品类,只需要关心所需产品对应的工厂
 
使用场景
- 实例化时有一定逻辑的,我都倾向于对外提供工厂方法,可以是在本类内提供,也可以单独搞个类,承担创建对象的职责。(extract method,extract class)
 - 当类的创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
 
工厂方法
定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
简单工厂封装了变化,但是当变化发生时,还是需要修改代码
类图

- IProduct: 定义工厂方法所创建对象的接口
 - ConcreteProduct: 实现Product接口
 - Factory:声明工厂方法,返回一个Product类型对象,也可以定义一个工厂方法的缺省实现;可以调用工厂方法以创建一个Product对象
 - ConcreteFactory:重定义工厂方法,返回一个ConcreteProduct实例
 
优点
- 简单工厂的优点
 - 扩展性高,扩展遵从开闭原则,新增产品通过添加产品类和对应产品的工厂类来实现,不需要修改原有代码
 
使用场景
- 同简单工厂,当类的创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
 - 当一个类不知道它所必须创建的对象的类的时候
 - 当一个类希望由它的子类来指定它所创建的对象的类的时候
 
实例
- ILoggerFactory todo 实例化过程分析
 
抽象工厂

定义: 提供一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。
动机: 产品 -> 产品族, 工厂 -> 抽象工厂
类图

- Factory: 声明创建抽象产品对象的操作接口
 - ConcreteFactory: 实现创建具体产品对象的操作,最好实现为singleton的。一个应用中一般每个产品系列只需要一个实例。
 - AbstractProduct: 为一类产品对象声明一个接口
 - ConcreteProduct: 定义一个被具体工厂创建的产品对象;实现AbstractProduct接口
 
优点
- 有利于产品的一致性
 - 开闭原则:
    
- 遵从:添加新的产品组合时,新增对应的工厂类即可。当需要更改一个产品组合时,修改配置即可。
 - 违反:添加新的产品时,所有的工厂类都需要添加对应的创建方法。
 - 定义可扩展的工厂:一种灵活但不太安全的设计是给创建对象的操作增加一个参数,AbstractFactory只需要一个工厂方法和元创建对象的种类的参数。
 
 
适用场景
- 产品之间有相互依赖,可以通过抽象工厂来处理产品的依赖,维护其一致性。
 
参考