设计模式-工厂模式

目录

🎗️1.工厂模式介绍

🎞️2.简单工厂模式

🎟️3.工厂方法模式

🎫4.抽象工厂方法模式

🎠5.测试


1.工厂模式介绍

  • 1.工厂模式属于创建型模式,它提供了一种创建对象的最佳方式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。
  • 2.工厂模式有三种不同的实现方式:
    • 简单工厂模式:通过传入相关的类型来返回相应的类,这种方式比较单一,可扩展性相对较差;
    • 工厂方法模式:通过实现类实现相应的方法来决定相应的返回结果,这种方式的可扩展性比较强;
    • 抽象工厂模式:基于上述两种模式的拓展,且支持细化产品
  • 应用场景
  • 解耦**:分离职责,把复杂对象的创建和使用的过程分开**
  • 复用代码降低维护成本**:**
    • 如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需用四处修改;
    • 使用工厂模式统一创建,则只要修改工厂类即可,降低成本;
  • 优点
  • 1、一个调用者想创建一个对象,只要知道其名称就可以了。
  • 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
  • 3、屏蔽产品的具体实现,调用者只关心产品的接口。
  • 缺点

每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。

2.简单工厂模式

  • 又称静态工厂方法,可以根据参数的不同返回不同类的实例,专门定义一个类来负责创建其他类的实例。被创建的实例通常都具有共同的父类
  • 由于工厂方法是静态方法,可通过类名直接调用,而且只需要传入简单的参数即可
  • 核心角色
  • Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑
  • IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,描述所有实例所共有的公共接口。
  • Product:具体产品类,是简单工厂模式的创建目标

2.1支付模拟

  • 1.创建支付接口
java 复制代码
/**
 * 统一支付接口
 */
public interface Pay {

    /**
     * 统一支付接口
     */
    void unifiedOrder();
}
  • 2.创建微信支付实现类
java 复制代码
/**
 * 微信支付
 */
public class WeChatPay implements Pay {
    @Override
    public void unifiedOrder() {
        System.out.println("微信支付~");
    }
}
  • 3.支付接调用类
java 复制代码
/**
 * 简单工厂模式
 */
public class SimplePayFactory {
    /**
     * 根据类型选择支付
     * @param payType
     */
    public static Pay toPay(String payType){
        if (payType==null){
            return null;
        }
        if (payType.equals("WeChat_PAY")){
            return new WeChatPay();
        }
        if (payType.equals("Ali_PAY")){
            return new AliPay();
        }
        return null;
    }
}
  • 优点

将对象的创建和对象本身业务处理分离可以降低系统的耦合度,使得两者修改起来都相对容易。

  • 缺点
  • 工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原则是相
  • 违背即开闭原则(Open Close Principle)对扩展开放,对修改关闭,程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果
  • 将会增加系统中类的个数,在一定程度上增加了系统的复杂度和理解难度,不利于系统的扩展和维护,创建简单对象就不用模式

3.工厂方法模式

  • 又称工厂模式,是对简单工厂模式的进一步抽象化
  • 其好处是可以使系统在不修改原来代码的情况下引进新的产品,即满足开闭原则
  • 通过工厂父类定义负责创建产品的公共接口,通过子类来确定所需要创建的类型
  • 相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性
  • 将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类。
  • 核心角色
  • 1.IProduct:抽象产品类,描述所有实例所共有的公共接口
  • 2.Product:具体产品类,实现抽象产品类的接口,工厂类创建对象,如果有多个需要定义多个
  • 3.IFactory:抽象工厂类,描述具体工厂的公共接口
  • 4.Factory:具体工场类,实现创建产品类对象,实现抽象工厂类的接口,如果有多个需要定义多个

3.1支付模拟

  • 1.创建支付接口
java 复制代码
/**
 * 统一支付接口
 */
public interface Pay {

    /**
     * 统一支付接口
     */
    void unifiedOrder();
}
  • 2.创建微信支付实现类
java 复制代码
/**
 * 微信支付
 */
public class WeChatPay implements Pay {
    @Override
    public void unifiedOrder() {
        System.out.println("微信支付~");
    }
}
  • 3.创建抽象工厂
java 复制代码
/**
 * 抽象工厂类
 */
public interface FactoryPatten {
    /**
     * 调用具体的支付方式
     * @return
     */
    Pay getPay();
}
  • 4.创建微信支付工厂
java 复制代码
/**
 * 微信支付具体实现类
 */
public class WeChatFactory implements FactoryPatten{
    /**
     * 创建微信支付支付对象
     * @return
     */
    @Override
    public Pay getPay() {
        return new WeChatPay();
    }
}
  • 5.创建支付宝支付工厂
java 复制代码
/**
 * 支付宝具体实现类
 */
public class AliPayFactory implements FactoryPatten{
    /**
     * 创建支付宝支付对象
     * @return
     */
    @Override
    public Pay getPay() {
        return new AliPay();
    }
}
  • 优点
  • 1.符合开闭原则,增加一个产品类,只需要实现其他具体的产品类和具体的工厂类;
  • 2.符合单一职责原则,每个工厂只负责生产对应的产品;
  • 3.使用者只需要知道产品的抽象类,无须关心其他实类,满足迪米特法则、依赖倒置原则和里氏替换原则;
    • 迪米特法则:最少知道原则,实体应当尽量少地与其他实体之间发生相互作用
    • 依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体
    • 里氏替换原则:俗称LSP,任何基类可以出现的地方,子类一定可以出现,对实现抽象化的具体步骤的规范
  • 缺点
  • 增加一个产品,需要实现对应的具体工厂类和具体产品类;
  • 每个产品需要有对应的具体工厂和具体产品类

4.抽象工厂方法模式

  • 1.抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂
  • 2.抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。
  • 3.通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。
  • 4.在一个产品族里面,定义多个产品,在一个工厂里聚合多个同类产品

4.1支付模拟

  • 1.创建支付工厂接口
java 复制代码
/**
 * 支付接口
 */
public interface PayFactory {

    /**
     * 统一支付接口
     */
    void unifiedOrder();
}
  • 2.创建退款工厂接口
java 复制代码
/**
 * 退款接口
 */
public interface RefundFactory {
    /**
     * 退款接口
     */
    void getRefund();
}
  • 3.创建订单接口,管理支付工厂合退款工厂
java 复制代码
/**
 * 订单接口,包括支付退和款
 */
public interface OrderFactory {

    /**
     * 创建支付
     * @return
     */
    PayFactory createPay();

    /**
     * 创建退款
     * @return
     */
    RefundFactory createRefund();
}
  • 4.创建微信支付实现工厂
java 复制代码
/**
 * 具体的微信支付实现类
 */
public class WeChatPay_a implements PayFactory {
    @Override
    public void unifiedOrder() {
        System.out.println("支付宝支付~");
    }
}
  • 5.创建微信退款实现工厂
java 复制代码
/**
 * 微信退款实现类
 */
public class WeChatRefund_a implements RefundFactory {
    @Override
    public void getRefund() {
        System.out.println("微信退款~");
    }
}
  • 6.创建微信订单实现工厂
java 复制代码
/**
 * 微信订单具体实现类
 */
public class WeChatOrder implements OrderFactory {
    //创建支付
    @Override
    public PayFactory createPay() {
        return new WeChatPay_a();
    }

    //创建退款
    @Override
    public RefundFactory createRefund() {
        return new WeChatRefund_a();
    }
}
  • 7.创建支付宝支付实现工厂
java 复制代码
/**
 * 具体的支付宝支付实现类
 */
public class AliPay_a implements PayFactory {
    @Override
    public void unifiedOrder() {
        System.out.println("支付宝支付~");
    }
}
  • 8.创建支付宝退款实现工厂
java 复制代码
/**
 * 具体的支付宝退款实现类
 */
public class AliRefund implements RefundFactory {
    @Override
    public void getRefund() {
        System.out.println("支付宝退款~");
    }
}
  • 9.创建支付宝订单实现工厂
java 复制代码
/**
 * 支付宝订单具体实现类
 */
public class AliOrder implements OrderFactory {
    //创建支付
    @Override
    public PayFactory createPay() {
        return new AliPay_a();
    }

    //创建退款
    @Override
    public RefundFactory createRefund() {
        return new AliRefund();
    }
}
  • 10.创建超级工厂,实现具体的订单方式
java 复制代码
/**
 *超级工厂创造器
 */
public class FactoryProduct {

    public static  OrderFactory getFactory(String type){
        if (type==null){
            return null;
        }
        if (type.equals("WeChat")){
            return new WeChatOrder();
        }else if (type.equals("Ali")){
            return new AliOrder();
        }
        return null;
    }
}
  • 优点

当一个产品族中的多个对象被设计成一起工作时,它能保证使用方始终只使用同一个产品族中的对象

  • 缺点
  • 产品族扩展困难,要增加一个系列的某一产品,既要在抽象的工厂和抽象产品里修改代码,又要在具体的里面加产品里加代码,不是很符合开闭原则
  • 增加了系统的抽象性和理解难度

5.测试

java 复制代码
/**
 * 测试实现
 */
public class MyTest {
    public static void main(String[] args) {
        /**
         * 根据不同的支付类型,调用相应的接口实现类
         */
        System.out.println("=======简单工厂模式=======");
        Pay pay1 = SimplePayFactory.toPay("Ali_PAY");
        Pay pay2 = SimplePayFactory.toPay("WeChat_PAY");
        pay1.unifiedOrder();
        pay2.unifiedOrder();
        System.out.println("=======简单工厂模式=======");
        System.out.println("+++++++++++++++++++++++++++++++++++++");
        System.out.println("=======工厂模式=======");
        //调用支付宝支付
        FactoryPatten aliPayFactory = new AliPayFactory();
        Pay aliPay = aliPayFactory.getPay();
        aliPay.unifiedOrder();
        //调用微信支付
        WeChatFactory weChatFactory = new WeChatFactory();
        Pay weChatPay = weChatFactory.getPay();
        weChatPay.unifiedOrder();
        System.out.println("=======工厂模式=======");
        System.out.println("=======抽象工厂模式=======");
        OrderFactory ali = FactoryProduct.getFactory("Ali");
        ali.createPay().unifiedOrder();
        ali.createRefund().getRefund();
        OrderFactory weChat = FactoryProduct.getFactory("WeChat");
        weChat.createPay().unifiedOrder();
        weChat.createRefund().getRefund();
        System.out.println("=======抽象工厂模式=======");
    }
}
相关推荐
不修×蝙蝠几秒前
八大排序--01冒泡排序
java
sky丶Mamba15 分钟前
Spring Boot中获取application.yml中属性的几种方式
java·spring boot·后端
数据龙傲天41 分钟前
1688商品API接口:电商数据自动化的新引擎
java·大数据·sql·mysql
feng_xiaoshi1 小时前
【云原生】云原生架构的反模式
云原生·架构
刷帅耍帅1 小时前
设计模式-桥接模式
设计模式·桥接模式
带带老表学爬虫1 小时前
java数据类型转换和注释
java·开发语言
千里码aicood1 小时前
【2025】springboot教学评价管理系统(源码+文档+调试+答疑)
java·spring boot·后端·教学管理系统
彭于晏6891 小时前
Android广播
android·java·开发语言
程序员-珍2 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
MinBadGuy2 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式