在说起简单工厂模式的时候,我们先看一段这样的话。。
现实生活中,原始社会自给自足(没有工厂),农耕社会小作坊(简单工厂,民间酒坊),工业革命流水线(工厂方法,自产自销),现代产业链代工厂(抽象工厂,富士康)。我们的项目代码同样是由简到繁一步一步迭代而来的,但对于调用者来说,却越来越简单。
在日常开发中,凡是需要生成复杂对象的地方,都可以尝试考虑使用工厂模式来代替
注意:
上述复杂对象指的是类的构造函数参数过多等对类的构造有影响的情况,因为类的构造过于复杂,如果直接在其他业务类内使用,则两者的耦合过重,后续业务更改,就需要在任何引用该类的源代码内进行更改,光是查找所有依赖就很消耗时间了,更别说要一个一个修改了。
一、工厂模式
1、工厂模式的定义
工厂模式的定义:
定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。
2、工厂模式的分类
按实际业务场景划分,工厂模式有 3 种不同的实现方式:
1.简单工厂模式
2.工厂方法模式
3.抽象工厂模式。
二、简单工厂模式定义与特点
1、简单工厂模式的定义
我们把被创建的对象称为“产品”,把创建产品的对象称为“工厂”。如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”。在简单工厂模式中创建实例的方法通常为静态(static)方法,因此简单工厂模式(Simple Factory Pattern)又叫作静态工厂方法模式(Static Factory Method Pattern)。
注意:
简单来说,简单工厂模式有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在 GoF 23 种设计模式之列。
2、简单工厂模式的优缺点
优点:
- 工厂类包含必要的逻辑判断,可以决定在什么时候创建哪一个产品的实例。客户端可以免除直接创建产品对象的职责,很方便的创建出相应的产品。工厂和产品的职责区分明确。
- 客户端无需知道所创建具体产品的类名,只需知道参数即可。
- 也可以引入配置文件,在不修改客户端代码的情况下更换和添加新的具体产品类。
缺点:
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。且工厂类代码会非常臃肿,违背高聚合原则。
- 使用简单工厂模式会增加系统中类的个数(引入新的工厂类),增加系统的复杂度和理解难度
- 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂
- 简单工厂模式使用了 static 工厂方法,造成工厂角色无法形成基于继承的等级结构。
三、简单工厂模式的结构与实现
1、模式的结构
简单工厂模式的主要角色如下:
- 简单工厂(SimpleFactory):是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(Product):是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
- 具体产品(ConcreteProduct):是简单工厂模式的创建目标。
2、模式的实现
代码示例
抽像产品类Product:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : Product* @description : [抽象产品]* @createTime : [2021/9/17 17:40]* @updateUser : [王振宇]* @updateTime : [2021/9/17 17:40]* @updateRemark : [描述说明本次修改内容]*/public interface Product {public void show();}
具体产品类ConcreteProduct1:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : ConcreteProduct1* @description : [具体产品1]* @createTime : [2021/9/17 17:43]* @updateUser : [王振宇]* @updateTime : [2021/9/17 17:43]* @updateRemark : [描述说明本次修改内容]*/public class ConcreteProduct1 implements Product{@Overridepublic void show() {System.out.println("具体产品1显示...");}}
具体产品类ConcreteProduct2:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : ConcreteProduct2* @description : [具体产品1]* @createTime : [2021/9/17 17:44]* @updateUser : [王振宇]* @updateTime : [2021/9/17 17:44]* @updateRemark : [描述说明本次修改内容]*/public class ConcreteProduct2 implements Product {@Overridepublic void show() {System.out.println("具体产品2显示...");}}
工厂实例化对象静态参数集Const:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : Const* @description : [工厂实例化对象静态参数集]* @createTime : [2021/9/17 17:45]* @updateUser : [王振宇]* @updateTime : [2021/9/17 17:45]* @updateRemark : [描述说明本次修改内容]*/public class Const {public static final int PRODUCT_A=0;public static final int PRODUCT_B=1;public static final int PRODUCT_C=2;}
简单工厂类SimpleFactory:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : SimpleFactory* @description : [简单工厂]* @createTime : [2021/9/17 17:48]* @updateUser : [王振宇]* @updateTime : [2021/9/17 17:48]* @updateRemark : [描述说明本次修改内容]*/public class SimpleFactory {public static Product makeProduct(int kind) {switch (kind) {case Const.PRODUCT_A:return new ConcreteProduct1();case Const.PRODUCT_B:return new ConcreteProduct2();}return null;}}
测试类SimpleFactoryTest:
package simple_factory.model;/*** @author : [王振宇]* @version : [v1.0]* @className : SimpleFactoryTest* @description : [简单工厂测试]* @createTime : [2021/9/18 10:36]* @updateUser : [王振宇]* @updateTime : [2021/9/18 10:36]* @updateRemark : [描述说明本次修改内容]*/public class SimpleFactoryTest {public static void main(String[] args) {Product product01 = SimpleFactory.makeProduct(0);product01.show();Product product02 = SimpleFactory.makeProduct(1);product02.show();}}
四、简单工厂模式应用场景
对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。
