• 软件设计模式白话文系列(八)桥接模式


    软件设计模式白话文系列(八)桥接模式

    1、描述

    把一个事物的多个维度剥离出来,通过组合方式来达到灵活设计的目的,Java 中,我们一般是通过对象引用来替换继承关系,从而将抽象和实现解耦合。

    桥接模式,可能大家只是不了解这个名称,但是我们的实际开发习惯基本都是有使用的。例如 spring 的注入功能(别说没用过哈)。所以说学习优秀的框架,就算没有去熟悉它的源码,精通它的底层逻辑,仅仅只是简单的使用都会在潜意识下提高我们的代码水平。

    2、模式结构与实现逻辑

    • 抽象化类:业务抽象类。引用不同维度的接口对象。在日常开发中我们习惯忽略这个类,改进为业务接口类,需引用的接口对象直接在扩展抽象化类直接引用。
    • 扩展抽象化类:抽象化类的子类,就是日常开发中的业务实现类。
    • 实现化类:维度接口类,一般有多个,一个事物维度对一个该类。
    • 具体实现化类:实现化类的实现类。

    本质的实现方式就是:业务类(扩展抽象化类)中引用其余业务类的父类或者接口(实现化类),在构造业务类时,根据需求动态传入其余业务类的具体实现类(具体实现类)。

    3、实战代码

    实战事例说明:

    模拟购买私有数字证书业务,私有数字证书分为 RootCA 证书、SubCA 证书、订户证书 三类,购买方式分为支付宝支付、微信支付两种。如果业务实现类通过继承或者实现接口方式来实现逻辑,就不考虑还有其他业务情况,就只是满足每种支付支付方式和每种证书类型创建就只少需要 6 个实现类来完成目标,显然这样会导致系统暴增。然后我们通过桥接模式只需要一个类就解决了。

    /**
     * 实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-13 00:01:54
     */
    public interface PayService {
        void pay();
    }
    
    /**
     * 实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:58:24
     */
    public interface CertService {
        void createCert();
    }
    
    /**
     * 抽象化类
     * 日常开发中一般没有抽象出这个类的
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:41:04
     */
    public abstract class BuyService {
        protected PayService payService;
        protected CertService certService;
    
        public BuyService(PayService payService, CertService certService) {
            this.payService = payService;
            this.certService = certService;
        }
    
        public abstract void BuyCert();
    }
    
    /**
     * 具体实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-13 00:01:54
     */
    public class AlipayServiceImpl implements PayService {
        @Override
        public void pay() {
            System.out.print("支付宝支付金额,开始");
        }
    }
    
    /**
     * 具体实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-13 00:01:54
     */
    public class WeChatServiceImpl implements PayService {
        @Override
        public void pay() {
            System.out.print("微信支付金额,开始");
        }
    }
    
    /**
     * 具体实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:59:44
     */
    public class RootCAServiceImpl implements CertService{
        @Override
        public void createCert() {
            System.out.println("创建 RootCA 证书");
        }
    }
    
    /**
     * 具体实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:59:44
     */
    public class SubCAServiceImpl implements CertService{
        @Override
        public void createCert() {
            System.out.println("创建 SubCA 证书");
        }
    }
    
    /**
     * 具体实现化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:59:44
     */
    public class CertServiceImpl implements CertService {
        @Override
        public void createCert() {
            System.out.println("创建订户证书");
        }
    }
    
    /**
     * 扩展抽象化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:41:04
     */
    public class BuyServiceImpl extends BuyService {
    
        public BuyServiceImpl(PayService payService, CertService certService) {
            super(payService, certService);
        }
    
        @Override
        public void BuyCert() {
            payService.pay();
            certService.createCert();
        }
    }
    
    /**
     * 测试类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-13 00:10:43
     */
    public class Client {
        public static void main(String[] args) {
            BuyService buyService = new BuyServiceImpl(new AlipayServiceImpl(), new RootCAServiceImpl());
            buyService.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService2 = new BuyServiceImpl(new WeChatServiceImpl(), new RootCAServiceImpl());
            buyService2.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService3 = new BuyServiceImpl(new WeChatServiceImpl(), new SubCAServiceImpl());
            buyService3.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService4 = new BuyServiceImpl(new AlipayServiceImpl(), new SubCAServiceImpl());
            buyService4.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService5 = new BuyServiceImpl(new WeChatServiceImpl(), new CertServiceImpl());
            buyService5.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService6 = new BuyServiceImpl(new AlipayServiceImpl(), new CertServiceImpl());
            buyService6.BuyCert();
            System.out.println("------------------------");
        }
    }
    

    执行结果:

    4、日常开发习惯代码

    作者平时开发代码时,是没有 BuyService 这个抽象类的,在平时开发中每个业务类都是先定义接口类,再进行实现,如果为了规范实现化类而抽象化出抽象类,会显得代码太过臃肿。

    作者一般是结合 lombok 的 @AllArgsConstructor 来实现目的

    /**
     * 抽象化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:41:04
     */
    public interface BuyService {
    
        public abstract void BuyCert();
    }
    
    /**
     * 扩展抽象化类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-12 23:41:04
     */
    @AllArgsConstructor
    public class BuyServiceImpl implements BuyService {
        private PayService payService;
        private CertService certService;
    
        @Override
        public void BuyCert() {
            payService.pay();
            certService.createCert();
        }
    }
    
    /**
     * 测试类
     *
     * @author Eajur.Wen
     * @version 1.0
     * @date 2022-11-13 00:10:43
     */
    public class Client {
        public static void main(String[] args) {
            BuyService buyService = new BuyServiceImpl(new AlipayServiceImpl(), new RootCAServiceImpl());
            buyService.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService2 = new BuyServiceImpl(new WeChatServiceImpl(), new RootCAServiceImpl());
            buyService2.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService3 = new BuyServiceImpl(new WeChatServiceImpl(), new SubCAServiceImpl());
            buyService3.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService4 = new BuyServiceImpl(new AlipayServiceImpl(), new SubCAServiceImpl());
            buyService4.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService5 = new BuyServiceImpl(new WeChatServiceImpl(), new CertServiceImpl());
            buyService5.BuyCert();
            System.out.println("------------------------");
    
            BuyService buyService6 = new BuyServiceImpl(new AlipayServiceImpl(), new CertServiceImpl());
            buyService6.BuyCert();
            System.out.println("------------------------");
        }
    }
    

    5、适用性

    • 当一个业务存在多个维度且维度会独立变化的时候。
    • 业务不希望使用继承或因为多层次继承而导致系统类暴增时。
  • 相关阅读:
    【React】classnames 库(可添加多个 className 类名)
    springboot过滤器拦截自定义异常
    利用Java EE相关技术实现一个简单的Web聊天室系统
    实战!如何从零搭建10万级 QPS 大流量、高并发优惠券系统--图文解析
    【TypeScript】中接口的详细介绍
    Spring boot 项目(二十五)——集成rocketmq实现简单的消息测试
    基于IDEA进行Maven工程构建
    Android 9.0 蓝牙功能之一:蓝牙电话
    【题解】JZOJ6703 tree
    大数据必学Java基础(一百一十一):过滤器注解应用和开发案例
  • 原文地址:https://www.cnblogs.com/eajur/p/16886544.html