1、工厂模式简介
⼯⼚模式介绍:它提供了⼀种创建对象的最佳⽅式,在创建对象时 不会对客户端暴露创建逻辑,并且是通过使⽤⼀个共同的接⼝来指向新创建的对象。
例⼦:
⼯⼚⽣产电脑,除了 A 品牌、还可以⽣产B、C、D品牌电脑;
业务开发中,⽀付很常⻅,⾥⾯有统⼀下单和⽀付接 ⼝,具体的⽀付实现可以微信、⽀付宝、银⾏卡等;
⼯⼚模式有 3 种不同的实现⽅式:
① 简单⼯⼚模式(静态工厂):通过传⼊相关的类型来返回相应的类,这 种⽅式⽐较单 ⼀,可扩展性相对较差。
② ⼯⼚⽅法模式:通过实现类实现相应的⽅法来决定相应的返回结果,这种⽅式的可扩展性⽐较强。
③ 抽象⼯⼚模式:基于上述两种模式的拓展,且⽀持细化产品。
应⽤场景:
解耦:分离职责,把复杂对象的创建和使⽤的过程分开。
复⽤代码 降低维护成本:如果对象创建复杂且多处需⽤到,如果每处都进⾏编写,则很多重复代码,如果业务逻辑发⽣了改 变,需⽤四处修改;使⽤⼯⼚模式统⼀创建,则只要修改⼯⼚类即可, 降低成本。
2、工厂模式——简单工厂模式
⼜称静态⼯⼚⽅法,可以根据参数的不同返回不同类的实例,专⻔定义⼀个类来负责创建其他类的实例,被创建的实例通常都具有共同的⽗类。由于⼯⼚⽅法是静态⽅法,可通过类名直接调⽤,⽽且只需要传⼊简单的参数即可。
核⼼组成:
Factory:⼯⼚类,简单⼯⼚模式的核⼼,它负责实现 创建所有实例的内部逻辑。
IProduct:抽象产品类,简单⼯⼚模式所创建的所有对象的⽗类,描述所有实例所共有的公共接⼝。
Product:具体产品类,是简单⼯⼚模式的创建⽬标。
实现步骤:
创建抽象产品类,⾥⾯有产品的抽象⽅法,由具体的产 品类去实现。
创建具体产品类,继承了他们的⽗类,并实现具体⽅法。
创建⼯⼚类,提供了⼀个静态⽅法createXXX()⽤来⽣产产品,只需要传⼊你想产品名称。
优点:将对象的创建和对象本身业务处理分离可以降低系统的 耦合度,使得两者修改起来都相对容易。
缺点:
⼚类的职责相对过重,增加新的产品需要修改⼯⼚类的判断逻辑,这⼀点与开闭原则是相违背。
即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进⾏拓展的时候,不能去修改原有的代码,实现⼀个热插拔的效果。
将会增加系统中类的个数,在⼀定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象就不⽤模式。
下面我们来简单使用一下简单(静态)工厂设计模式:
我们简单使用伪代码模拟一下支付流程:
创建 IProduct 抽象产品接口——IPay:
/**
* @Auther: csp1999
* @Date: 2020/11/07/11:00
* @Description: IPay 抽象统一支付下单接口
*/
public interface IPay {
/**
* 统一下单
*/
void unifiedOrder();
}
创建 Product 具体产品类——AliPay/WeChatPay:
AliPay.java
/**
* @Auther: csp1999
* @Date: 2020/11/07/11:29
* @Description: 支付宝支付具体实现类
*/
public class AliPay implements IPay{
@Override
public void unifiedOrder() {
System.out.println("支付宝支付统一下单...");
}
}
WeChatPay.java
/**
* @Auther: csp1999
* @Date: 2020/11/07/11:30
* @Description: 微信支付具体实现类
*/
public class WeChatPay implements IPay{
@Override
public void unifiedOrder() {
System.out.println("微信支付统一下单...");
}
}
创建Factory工厂类——SimplePayFactory:
/**
* @Auther: csp1999
* @Date: 2020/11/07/11:31
* @Description: 简单支付工厂类(静态工厂类)
*/
public class SimplePayFactory {
/**
* 工厂创建方法:
* 根据参数返回对应的支付对象
*
* @param payType
* @return
*/
public static IPay createPay(String payType) {
if (payType == null) {
return null;
} else if (payType.equalsIgnoreCase("WECHAT_PAY")) {
return new WeChatPay();
} else if (payType.equalsIgnoreCase("ALI_PAY")) {
return new AliPay();
}
// 如果需要扩展,可以编写更剁
return null;
}
}