设计模式 - 简单工厂模式(Simple Factory Pattern)
设计模式 - 简单工厂模式(Simple Factory Pattern)
概要
记忆关键字:工厂类创建对象
定义:通过工厂类创建对象,并且根据传入参数决定具体子类对象的做法,就是简单工厂模式。
分析:如果一个类的实例需要在许多地方被创建和初始化,而初始化的代码也比较复杂。此时可以考虑使用简单工厂模式
简单工厂模式不是一个正式的设计模式,但它是工厂模式的基础。它使用一个单独的工厂类来创建不同的对象,根据传入的参数决定创建哪种类型的对象。
简单工厂模式结构图如下:
一、能解决什么问题?
创建对象需要一系列复杂的初始化操作,比如关联其他成员对象,查配置文件,查数据表等,若将这些初始化逻辑写在构造函数里,会降低程序的可读性,此时可以考虑是用简单工厂模式。
二、涉及的角色
1. IProduct: 抽象产品角色
所有产品实例的接口,负责描述所有产品实例的行为
1 public interface IVender { 2 /** 3 * 供应商下单方法 4 */ 5 void order(); 6 }
2. Product 具象产品角色
所有产品的实例,实现了抽象产品定义的代码,代码示例如下:
1 public class VendorA implements IVender{ 2 @Override 3 public void order() { 4 // 业务逻辑处理 5 System.out.println("A供应商下单成功,下单时间" + new Date()); 6 } 7 } 8 9 10 public class VendorB implements IVender { 11 @Override 12 public void order() { 13 // 业务逻辑处理 14 System.out.println("B供应商下单成功,下单时间:" + new Date()); 15 } 16 }
3. 工厂角色:Factory
负责根据不同的参数创建不同的实例
1 public class VendorFactory { 2 public static IVender createVendor(String type) { 3 switch (type) { 4 case "A": 5 return new VendorA(); 6 case "B": 7 return new VendorB(); 8 default: 9 throw new RuntimeException("供应商不存在"); 10 } 11 } 12 }
4. 客户端类 Client
传入类型的名称,通过工厂类创建对象,代码示例如下:
1 public class Client { 2 public static void main(String[] args) { 3 String type = "A"; 4 IVender iVender = VendorFactory.createVendor(type); 5 iVender.order(); 6 } 7 } 8 9 //运行结果 10 A供应商下单成功,下单时间Wed Jul 31 17:20:21 CST 2024
三、缺点分析
1. 优点
工厂类中包含了必要的逻辑判断,根据客户端选择的条件动态实例化相关的类,对于客户端,去除了与具体产品的依赖。
2. 缺点
违背了开放-关闭原则:在增加新的子类的时候,工厂类的方法中就要增加新的条件分支判断,这就等于不但对扩展开放了,对修改也开放了。
3. 分析
所有在用简单工厂的地方,都可以考虑使用发射技术来去除switch或if,解除分支判断带来的耦合
4. 项目中的使用
Spring Boot 框架本身并没有直接使用简单工厂模式,因为框架本身更倾向于使用依赖注入和控制反转等设计模式。但是,在实际的Spring Boot项目中,业务代码中经常能用到,在某些场景下,还可以与策略模式模式结合起来使用。
四、使用场景
大多数情况下,直接使用new关键字来创建对象是没有问题的。而如果创建对象需要一系列复杂的初始化操作,比如关联其他成员对象,查配置文件,查数据表等,若将这些初始化逻辑写在构造函数里,会降低程序的可读性,此时可以考虑是用简单工厂模式。
在以下情况下可以使用简单工厂模式:
1)工厂类负责创建的对象比较少
由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
2)客户端只知道传入工厂类的参数,对于如何创建对象不关心
客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。