设计模式之工厂模式

1.工厂模式概念介绍

  • 它提供了一种创建对象的最佳方式,我们在创建对象时,不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象

  • 3种实现方式

    • 简单工厂模式:通过传入相关的类型来返回对应的类,这种方式比较单一,可扩展性相对较差
    • 工厂方法模式:通过实现类实现对应的方法来决定相应的返回结果,这种方式的可扩展项比较强
    • 抽象工厂模式:基于上述两种模式的扩展,是工厂方法模式的升级版,当需要创建的产品有多个产品线时使用,抽象工厂模式是比较好的选择;抽象工厂模式是Spring中应用最为广泛的一种设计模式
  • 优点

    • 解耦:分离职责,把复杂对象的创建和使用的过程分开
    • 复用代码,降低维护成本
  • 应用场景

    • 支付:统一下单和支付接口,具体支付实现可以微信、支付宝、银行卡等

2.简单工厂模式

  • 简单工厂模式

    • 又称静态工厂方法,可以根据参数的不同返回不同类的实例,专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类
    • 由于工厂方法是静态方法,可通过类名直接调用,而且只需要传入简单的参数即可
  • 核心组成

    • Factory:工厂类,简单工厂模式的核心,它负责实现创建所有实例的内部逻辑
    • IProduct:抽象产品类,简单工厂模式所创建的所有对象的父类,描述所有实例所共有的公共接口
    • Product:具体产品类,是简单工厂模式的创建目标
  • 优点

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

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

    /**
     * 接口:定义规范
     */
    interface Pay {
    
        /**
         * 统一下单方法
         */
        void unifiedOrder();
    }
    
    /**
     * 支付宝
     */
    class AliPay implements Pay {
        @Override
        public void unifiedOrder() {
            System.out.println("支付宝支付");
        }
    }
    
    /**
     * 微信支付
     */
    class WechatPay implements Pay {
    
        @Override
        public void unifiedOrder() {
            System.out.println("微信支付");
        }
    }
    
    /**
     * 简单工厂模式
     */
    class SimplePayFactory {
        /**
         * 根据参数,返回对应的支付对象
         *
         * @param payType
         * @return
         */
        public static Pay createPay(String payType) {
            if ("ALI_PAY".equalsIgnoreCase(payType)) {
                return new AliPay();
            } else if ("WECHAT_PAY".equalsIgnoreCase(payType)) {
                return new WechatPay();
            }
            // TODO: 拓展时,增加if-else语句
            return null;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            SimplePayFactory.createPay("WECHAT_PAY").unifiedOrder();
        }
    }
    

3.工厂方法模式

  • 工厂方法模式

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

    • IProduct:抽象产品类,描述所有实例所共有的公共接口

    • Product:具体产品类,实现抽象产品类的接口,工厂类创建对象,如果有多个需要定义多个

    • IFactory:抽象工厂类,描述具体工厂的公共接口

    • Factory:具体工厂类,实现创建产品类对象,实现抽象工厂类的接口,如果有多个需要定义多个

      在这里插入图片描述

  • 优点

    • 符合开闭原则,增加一个产品类,只需要实现其它具体的产品类和具体的工厂类
    • 符合单一职责原则,每个工厂只负责生产对应的产品
    • 使用者只需要知道产品的抽象类,无需关心其他实现类,满足迪米特法则、依赖倒置原则和里氏替换原则
      • 迪米特法则:最少知道原则,实体应当尽量少地与其他实体之间发生相互作用
      • 依赖倒置原则:针对接口编程,依赖于抽象而不依赖于具体
      • 里氏替换原则:俗称LSP,任何基类可以出现的地方,子类一定可以出现,对实现抽象化的具体步骤的规范
  • 缺点

    • 增加一个产品,需要实现对应的具体工厂类和具体产品类
    • 每个产品需要对应的具体工厂和具体产品类
  • 代码示例

    /**
     * 接口:定义规范
     */
    interface Pay {
    
        /**
         * 统一下单方法
         */
        void unifiedOrder();
    }
    
    /**
     * 支付宝
     */
    class AliPay implements Pay {
        @Override
        public void unifiedOrder() {
            System.out.println("支付宝支付");
        }
    }
    
    /**
     * 微信支付
     */
    class WechatPay implements Pay {
    
        @Override
        public void unifiedOrder() {
            System.out.println("微信支付");
        }
    }
    
    /**
     * 抽象工厂方法
     */
    interface PayFactory {
        Pay getPay();
    }
    
    class AliPayFactory implements PayFactory {
        @Override
        public Pay getPay() {
            return new AliPay();
        }
    }
    
    class WechatPayFactory implements PayFactory {
        @Override
        public Pay getPay() {
            return new WechatPay();
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            new AliPayFactory().getPay().unifiedOrder();
            new WechatPayFactory().getPay().unifiedOrder();
        }
    }
    

4.抽象工厂模式

  • 背景

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

    在这里插入图片描述

  • 优点

    • 当一个产品族中的多个对象被设计成一起工作时,它能保证使用方始终只使用同一个产品族中的对象
    • 产品等级结构扩展容易,如果需要增加多一个产品等级,只需要增加新的工厂类和产品类即可,比如增加银行支付、退款
  • 缺点

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

    /**
     * 超级工厂,定义同个产品族的其他相关子工厂
     */
    interface OrderFactory {
        PayFactory createPay();
    
        RefundFactory createRefund();
    }
    
    /**
     * 支付抽象接口
     */
    interface PayFactory {
        void unifiedOrder();
    }
    
    /**
     * 退款抽象接口
     */
    interface RefundFactory {
        void refund();
    }
    
    /**
     * 支付宝支付
     */
    class AliPay implements PayFactory {
        @Override
        public void unifiedOrder() {
            System.out.println("支付宝支付");
        }
    }
    
    /**
     * 支付宝退款
     */
    class AliRefund implements RefundFactory {
        @Override
        public void refund() {
            System.out.println("支付宝退款");
        }
    }
    
    /**
     * 微信支付
     */
    class WechatPay implements PayFactory {
        @Override
        public void unifiedOrder() {
            System.out.println("微信支付");
        }
    }
    
    /**
     * 微信退款
     */
    class WechatRefund implements RefundFactory {
        @Override
        public void refund() {
            System.out.println("微信退款");
        }
    }
    
    /**
     * 产品族工厂
     */
    class AliOrderFactory implements OrderFactory {
        @Override
        public PayFactory createPay() {
            return new AliPay();
        }
    
        @Override
        public RefundFactory createRefund() {
            return new AliRefund();
        }
    }
    
    /**
     * 产品族工厂
     */
    class WechatOrderFactory implements OrderFactory {
        @Override
        public PayFactory createPay() {
            return new WechatPay();
        }
    
        @Override
        public RefundFactory createRefund() {
            return new WechatRefund();
        }
    }
    
    /**
     * 超级工厂生产器,简单工厂模式
     */
    class FactoryProducer {
        public static OrderFactory createFactory(String type) {
            if ("ALI".equalsIgnoreCase(type)) {
                return new AliOrderFactory();
            } else if ("WECHAT".equalsIgnoreCase(type)) {
                return new WechatOrderFactory();
            }
            return null;
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            OrderFactory ali = FactoryProducer.createFactory("ALI");
            ali.createPay().unifiedOrder();
            ali.createRefund().refund();
            OrderFactory wechat = FactoryProducer.createFactory("WECHAT");
            wechat.createPay().unifiedOrder();
            wechat.createRefund().refund();
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gen邓艮艮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值