02-03.(创建型模式)java设计模式之工厂方法模式与抽象工厂模式

一、什么是工厂模式

1.1⼯⼚模式有 3 种不同的实现⽅式:

简单⼯⼚模式(没有在23种设计模式中):通过传⼊相关的类型来返回相应的类,这种⽅式⽐较单 ⼀,可扩展性相对较差;

⼯⼚⽅法模式:通过实现类实现相应的⽅法来决定相应的返回结果,这种⽅式的可扩展性⽐较强;

抽象⼯⼚模式:基于上述两种模式的拓展,且⽀持细化产品;

1.2产品族与产品等级结构(参考https://www.jianshu.com/p/f1e837cab952

产品族:产品的继承结构。单位:一个产品族。

产品等级结构:不同的产品等级结构的一组产品组成产品族。 单位:一个产品等级。

案例分析:二中的三个案例用的付款案例。其中付款、退款组成两个产品等级。支付宝支付与微信支付为两个产品族。

二、工厂方法的实现方式

  2.1简单⼯⼚模式

模式结构分析:

  • ⼜称静态⼯⼚⽅法, 可以根据参数的不同返回不同类的实例,专⻔定义⼀个类来负责创建其他类的实例,被创建的实例通常都具有共同的⽗类
  • 由于⼯⼚⽅法是静态⽅法,可通过类名直接调⽤,⽽且只需要传⼊简单的参数即可

类关系图:

代码实现:

查看代码
//具体实现 
public class AliPay implements IPay{
    @Override
    public void unifiedOrder() {
        System.out.println("支付宝支付统一下单...");
    }
}
//具体实现
public class WeChatPay implements IPay {
    @Override
    public void unifiedOrder() {
        System.out.println("微信支付统一下单...");
    }
}
//下单功能 产品等级结构的定义
public interface IPay {
    /**
     * 统一下单
     */
    void unifiedOrder();
}
//简单工厂
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;
    }
}

测试:

@Test
public void simplePayFactoryTest(){
    IPay pay= SimplePayFactory.createPay("WECHAT_PAY");
    pay.unifiedOrder();
}

 运行结果:微信支付统一下单...

方法评估:

  • 优点:
    • 将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。
  • 缺点
    • ⼯⼚类的职责相对过重,增加新的产品需要修改⼯⼚类的判断逻辑,这⼀点与开闭原则是相违背。即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进⾏拓展的时候,不能去修改原有的代码,实现⼀个热插拔的效果

2.2工厂方法模式

模式结构分析:

  • ⼜称⼯⼚模式,是对简单⼯⼚模式的进⼀步抽象化,其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满⾜开闭原则。
  • 通过⼯⼚⽗类定义负责创建产品的公共接⼝,通过⼦类来确定所需要创建的类型相⽐简单⼯⼚⽽⾔,此种⽅法具有更多的可扩展性和复⽤性,同时也增强了代码的可读性。
  • 将类的实例化(具体产品的创建)延迟到⼯⼚类的⼦类(具体⼯⼚)中完成,即由⼦类来决定应该实例化哪⼀个类。

类关系图:

 

工厂方法统一模型:

 

代码实现:

查看代码
public class AliPay implements IPay{
    @Override
    public void unifiedOrder() {
        System.out.println("支付宝支付统一下单...");
    }
}
public class WeChatPay implements IPay {
    @Override
    public void unifiedOrder() {
        System.out.println("微信支付统一下单...");
    }
}
//产品等级结构的定义
public interface IPay {
    /**
     * 统一下单
     */
    void unifiedOrder();
}

public class AliPayFactory implements IPayFactory {
    @Override
    public IPay getPay() {
        return new AliPay();
    }
}
public class WeChatPayFactory implements IPayFactory{
    @Override
    public IPay getPay() {
        return new WeChatPay();
    }
}
//产品族的定义
public interface IPayFactory {
    IPay getPay();
}

测试:

/*
*工厂方法
* */
@Test
public void mathodPayFactoryTest(){
    /*
    * 微信支付
    * */
    IPayFactory payFactory=new WeChatPayFactory();
    payFactory.getPay().unifiedOrder();
    /*
    * 阿里支付
    * */
    IPayFactory payFactory1=new AliPayFactory();
    payFactory1.getPay().unifiedOrder();
}

方法评估:

优点:

  • 符合开闭原则,增加⼀个产品类,只需要实现其他具体的产品类和具体的⼯⼚类;
  • 符合单⼀职责原则,每个⼯⼚只负责⽣产对应的产品使⽤者只需要知道产品的抽象类,⽆须关⼼其他实现类,满⾜迪⽶特法则、依赖倒置原则和⾥⽒替换原则
    • 迪⽶特法则:最少知道原则,实体应当尽量少地与其他实体之间发⽣相互作⽤
    • 依赖倒置原则:针对接⼝编程,依赖于抽象⽽不依赖于具体
    • ⾥⽒替换原则:俗称LSP, 任何基类可以出现的地⽅,⼦类⼀定可以出现, 对实现抽象化的具体步骤的规范

缺点:

  • 增加⼀个产品,需要实现对应的具体⼯⼚类和具体产品类;每个产品需要有对应的具体⼯⼚和具体产品类

2.3抽象工厂

      基于上述两种模式的拓展,是⼯⼚⽅法模式的升级版,当需要创建的产品有多个产品线时使⽤抽象⼯⼚模式是⽐较好的选择。 这里面涉及产品族与产品等级的概念。

  •  定义产品等级接口   as : Pay, Refund。
  • 创建具体的产品 as: AliPay,WechatPay, AiliRefund,WechatRefund。
  • 创建产品族接口  as:OrderFactory 里面有createPay/createRefund。
  • 创建具体产品族 as:  AliOderFactory,WechatOderFactory。
  • 定义一个超级工厂创造器,通过传递参数获取对应的工厂。

类关系图:

 

代码实现:

查看代码
//产品等级结构
public interface IPay {
    /**
     * 统一下单
     */
    void unifiedOrder();
}
public interface IRefund {
    void refund();
}
public class AliPay implements IPay{
    @Override
    public void unifiedOrder() {
        System.out.println("支付宝支付统一下单...");
    }
}
public class WeChatPay implements IPay {
    @Override
    public void unifiedOrder() {
        System.out.println("微信支付统一下单...");
    }
}
public class AliRefund implements IRefund{
    @Override
    public void refund() {
        System.out.println("阿里退款统一下单...");
    }
}
public class WeChatRefund implements IRefund {
    @Override
    public void refund() {
        System.out.println("微信退款统一下单...");
    }
}
// 产品族的定义
public interface IOrderFactory {
    IPay createPay();
    IRefund createRefund();
}
public class AliOderFactory  implements IOrderFactory{
    @Override
    public IPay createPay() {
        return new AliPay();
    }

    @Override
    public IRefund createRefund() {
        return new AliRefund();
    }
}
public class WechatOderFactory implements IOrderFactory{
    @Override
    public IPay createPay() {
        return new WeChatPay();
    }

    @Override
    public IRefund createRefund() {
        return new WeChatRefund();
    }
}

测试:

  @Test
    public void abstractPayFactoryTest(){
        //ali的付款方式
        IOrderFactory aliFactory=new AliOderFactory();
        aliFactory.createPay().unifiedOrder();
        aliFactory.createRefund().refund();
    }
}

测试结果:

支付宝支付统一下单...
阿里退款统一下单...

方法评估:

  • ⼯⼚⽅法模式引⼊⼯⼚等级结构,解决了简单⼯⼚模式中⼯⼚类职责过重的问题。
  • 但⼯⼚⽅法模式中每个⼯⼚只创建⼀类具体类的对象,后续发展可能会导致⼯⼚类过多,因此将⼀些相关的具体类组成⼀个“具体类族”,由同⼀个⼯⼚来统⼀⽣产,强调的是⼀系列相关的产品对象!!!

三: 汇总

针对抽象出来的产品族与产品等级;以此来解释工厂方法与抽象工厂方法。

工厂方法:单个产品等级的多个产品族的。

抽象工厂方法:多个产品等级与多个产品族的。

posted @   冰融心  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示