设计模式-工厂模式

目录

🎗️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("=======抽象工厂模式=======");
    }
}
相关推荐
皓木.1 分钟前
苍穹外卖——准备工作
java·数据库·mybatis
time_silence3 分钟前
微服务——不熟与运维
运维·微服务·架构
-指短琴长-4 分钟前
Docker之技术架构【八大架构演进之路】
docker·容器·架构
Q_192849990613 分钟前
基于Spring Boot的旅游推荐系统
spring boot·后端·旅游
愤怒的代码15 分钟前
Spring Boot对访问密钥加密解密——RSA
java·spring boot·后端
美美的海顿16 分钟前
springboot基于Java的校园导航微信小程序的设计与实现
java·数据库·spring boot·后端·spring·微信小程序·毕业设计
愤怒的代码17 分钟前
Spring Boot中幂等性的应用
java·spring boot·后端
silver68719 分钟前
JAVA8 Stream API 使用详解
java
武子康21 分钟前
大数据-259 离线数仓 - Griffin架构 修改配置 pom.xml sparkProperties 编译启动
xml·java·大数据·hive·hadoop·架构
xiaocaibao7771 小时前
编程语言的软件工程
开发语言·后端·golang