模式定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。提供一个创建对象实例的功能,而无需关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体类。
解决的问题
将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。即使用者可直接消费产品而不需要知道其生产的细节。
适用的环境
工厂类创建的对象比较小,这样不会造成工厂方法中业务的逻辑过于复杂。
客户端只是知道传入工厂类的参数、对于如何去创建对象并不关心。客户端不需要去关心创建的细节,只需要明确需要的参数,而由工厂内部负责具体的类的创建。
模式原理
模式组成
组成(角色) | 关系 | 作用 |
---|---|---|
抽象产品(Product) | 具体产品的父类 | 描述产品的公共接口 |
具体产品(Concrete Product) | 抽象产品的子类; 工厂类创建的目标类 | 描述生产的具体产品 |
工厂(Creator) | 被外界调用 | 根据传入不同参数从而创建不同具体产品类的实例 |
UML类图
使用步骤
- 创建抽象产品类 & 定义具体产品的公共接口;
- 创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
- 创建工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
- 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例
模式优点
责任分割:工厂类含有处理逻辑,决定何时去创建产品对象,客户端只是需要传递对应的参数,即可以完成产品的创建。
在一定程度上提高了系统的灵活性:可以通过引入配置文件的方法,在不去修改客户端代码的前提下,更换和增减新的产品。
模式缺点
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响。
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
模式应用
- JDK类库中广泛使用了简单工厂模式,如工具类java.text.DateFormat,它用于格式化一个本地日期或者时间。
1 | public final static DateFormat getDateInstance(); |
- 获取不同加密算法的密钥生成器。
1 | KeyGenerator keyGen=KeyGenerator.getInstance("DESede"); |
模式示例
以生产电脑为例,假设有一个电脑的代工生产商,它目前已经可以代工生产联想电脑,随着业务的拓展,这个代工生产商还要生产惠普和华硕的电脑,这样就需要用一个单独的类来专门生产电脑,这就用到了简单工厂模式。
抽象产品类
创建一个电脑的抽象产品类,他有一个抽象方法用于启动电脑生产:
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |
具体产品类
接着创建各个品牌的电脑,他们都继承了他们的父类Computer,并实现了父类的startProduce方法:
联想电脑
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |
惠普电脑
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |
华硕电脑
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |
工厂类
接下来创建一个工厂类,它提供了一个静态方法createComputer用来生产电脑。你只需要传入你想生产的电脑的品牌,它就会实例化相应品牌的电脑对象:
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |
客户端
客户端调用工厂类,传入“asus”生产出华硕电脑并调用该电脑对象的startProduce方法:
1 | package main.java.com.study.designPatterns.simpleFactoryPattern.demoOne; |