工厂方法模式Factory Method
工厂方法 Factory Method
工厂方法模式是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
工厂模式分为:简单工厂、工厂方法、抽象工厂。
为什么要使用?
工厂方法模式的对象职责:
在父类中提供一个创建对象的方法, 允许子类决定实例化对象的类型。换句话说,父类只需要知道它能创建对象,具体什么是实例对象让子类去考虑。
例如在实际开发中,你需要用户能够去自定义组件,那么你就需要制定一套规则,让用户依照你的规则去开发。工厂方法模式🏭就是非常好的选择。它能够让创建产品和使用产品分离,那么用户就可以在不修改核心代码的同时,更改为自定义组件。
父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的类全部交由子类去负责。这样就能让创建者和具体产品解耦。
模式结构
- 产品 (Product) 将会对接口进行声明。 对于所有由创建者及其子类构建的对象, 这些接口都是通用的。
- 具体产品 (Concrete Products) 是产品接口的不同实现。
- 创建者 (Creator) 类声明返回产品对象的工厂方法。 该方法的返回对象类型必须与产品接口相匹配。注意, 并不一定每次调用工厂方法都会创建新的实例。 工厂方法也可以返回缓存、 对象池或其他来源的已有对象。
- 具体创建者 (Concrete Creators) 将会重写基础工厂方法, 使其返回不同类型的产品。
工厂方法模式的类图:
Creator
类只需要知道 create()
方法可以创建出 Product
,而不需要知道其他具体实现。
当我们更换实现为新的 ConcreteCreator
类时,那么 create()
方法创建的 ConcreteProduct
也会更改。如果 Creator
类中能够创建不同的 Product
时,它就离抽象工厂更近一步了。
工厂方法模式侧重于直接对具体产品的实现进行封装和调用,通过统一的接口定义来约束程序的对外行为。
模式实现
该示例使用工厂方法模式来构建 Dialog
和 Button
的关系,并提供了一套默认样式。该模式使得用户也可以自定义样式,只需要继承抽象类并实现。
示例程序的类图
代码实现
抽象创建者 Creator
1 | package example.framework; |
抽象产品 Product
1 | package example.framework; |
默认实现
1 | package example.concrete; |
1 | package example.concrete; |
自定义实现
1 | package example.my; |
1 | package example.my; |
代码测试
1 | import example.concrete.DefaultDialog; |
输出结果
1 | | Button | |
由上述可以看出,我们不需要去修改默认实现类就可以将样式替换成自定义的。
常用场景和解决方案
- 有限、可重用的对象,使用工厂方法模式可以有效节约资源,例如:
- 需要使用很多重复代码创建对象时,比如,
DAO
层的数据对象、API
层的VO
对象等。 - 创建对象要访问外部信息或资源时,比如,读取数据库字段、获取访问授权 token 信息、配置文件等。
- 创建需要统一管理生命周期的对象时,比如,会话信息、用户网页浏览轨迹对象等。
- 创建池化对象时,比如,连接池对象、线程池对象、日志对象等。
- 需要使用很多重复代码创建对象时,比如,
- 希望隐藏对象的真实类型时,比如,不希望使用者知道对象的真实构造函数参数等。
- 不确定对象确切类别及其依赖关系时,可以使用工厂方法。工厂方法能让你在使用时不考虑它以后可能会拓展的具体实现。
- 如果你希望用户能扩展你软件库或框架的内部组件,可使用工厂方法。
模式的优缺点
优点 | 缺点 |
---|---|
你可以避免创建者和具体产品之间的紧密耦合。 | 应用工厂方法模式需要引入许多新的子类, 代码可能会因此变得更复杂。 最好的情况是将该模式引入创建者类的现有层次结构中。 |
能根据用户的需求定制化地创建对象。 | 具体工厂实现逻辑不统一,增加代码理解难度。 |
隐藏了具体使用哪种产品来创建对象。 | |
单一职责原则。 你可以将产品创建代码放在程序的单一位置, 从而使得代码更容易维护。 | |
开闭原则。 无需更改现有客户端代码, 你就可以在程序中引入新的产品类型。 |
拓展知识
- 在许多设计工作的初期都会使用工厂方法模式(较为简单, 而且可以更方便地通过子类进行定制),随后演化为使用抽象工厂模式、原型模式或生成器模式(更灵活但更加复杂)。
- 抽象工厂模式通常基于一组工厂方法,但你也可以使用原型模式来生成这些类的方法。
- 工厂方法和抽象工厂的区别:
- 工厂方法模式侧重于继承的连续性,核心为“里氏替换原则”;而抽象工厂模式侧重于组合的拓展性,核心为“分析共性,找出更好的抽象产品”。
- 工厂方法适用单产品,抽象工厂适用于多产品。
🔙 设计模式
📌最后:希望本文能够给您提供帮助,文章中有不懂或不正确的地方,请在下方评论区💬留言!
🔗参考文献:
📖 图解设计模式 /(日)结城浩著;杨文轩译. –北京:人民邮电出版社,2017.1
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hellovie's Blog!
评论