• 10【桥接设计模式】


    十、桥接设计模式

    10.1 桥接设计模式简介

    10.1.1 桥接设计模式概述

    桥接模式(Bridge Pattern):将抽象部分与实现部分分离,使得它们可以独立变化。

    Tips:需要注意的是,桥接模式中的抽象并不是指抽象类或接口这种硬性概念,实现也不是具体指实现类;抽象与实现分离指的是两种维度的分离。这需要我们继续学习后面的知识;

    桥接模式主要的目的就是用组合/聚合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。

    【案例】

    我们需要创建不同品牌的不同设备,这种关系使用继承来描述如下:

    在这里插入图片描述

    设计好继承体系后,我们发现类的数量非常非常多,如果需要新增一个品牌或者新增一个设备都会导致类的数量激增;因为一个品牌都有手机、电脑、相机等设备。一个设备也会有小米、华为、神舟等品牌;这样一来不利于后期的维护。

    • 在上述案例中,可将系统划分为两个纬度:

    在这里插入图片描述

    所谓抽象与实现的分离指的是:不直接编写小米手机类、小米电脑类去继承小米这个品牌。而是将系统分为两个纬度(品牌、设备)一个为抽象纬度(品牌),一个为实现纬度(设备)进行抽象化;这样抽象与实现就进行分离了。

    10.1.2 桥接设计模式的UML类图

    桥接模式中,主要包含4个角色:

    • 1)抽象角色(Abstraction):确定抽象纬度的产品基本操作,该类持有一个对具体实现角色的引用,其构造函数规定子类需要传递一个具体的实现对象,抽象角色是桥接模式用于组合的关键;
    • 2)具体抽象角色(Refined Abstraction):Abstraction的具体实现,对Abstraction的方法进行实现;
    • 3)实现角色(Implementor):确定实现纬度的产品基本操作,提供给Abstraction使用;
    • 4)具体实现角色(Concrete Implementor):Implementor的具体实现;

    在这里插入图片描述

    10.2 桥接模式的实现

    桥接模式将系统体系划分为了多个纬度来看待;多个纬度采用组合的方式来进行代码的解耦;

    我们将产品作为实现纬度,品牌作为抽象纬度来设计系统的体系;

    • 抽象角色-产品:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 抽象角色
     */
    public abstract class Product {
    
        // 使用组合关系关联产品的品牌(包含具体实现角色的引用)
        protected Brand brand;
    
        public Product(Brand brand) {
            this.brand = brand;
        }
    
        public abstract String getProduct();
    
        public void show() {
            System.out.println("您正在使用【" + brand.getBrand() + "】牌【" + getProduct() + "】");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 具体抽象角色1-手机产品:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体抽象角色
     */
    public class PhoneProduct extends Product {
        public PhoneProduct(Brand brand) {
            super(brand);
        }
    
        @Override
        public String getProduct() {
            return "手机";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 具体抽象角色2-电脑产品:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体实现角色
     */
    public class ComputerProduct extends Product {
    
        public ComputerProduct(Brand brand) {
            super(brand);
        }
    
        @Override
        public String getProduct() {
            return "电脑";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 实现角色-品牌:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:  实现角色
     */
    public interface Brand {
        String getBrand();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 具体实现角色1-小米品牌:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体实现角色
     */
    public class XiaoMiBrand implements Brand {
        @Override
        public String getBrand() {
            return "小米";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 具体实现角色2-华为品牌:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro: 具体实现角色
     */
    public class HuaWeiBrand implements Brand {
        @Override
        public String getBrand() {
            return "华为";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 测试类:
    package com.dfbz.demo01;
    
    /**
     * @author lscl
     * @version 1.0
     * @intro:
     */
    public class Demo01 {
        public static void main(String[] args) {
            Brand brand = new XiaoMiBrand();
            Product product = new ComputerProduct(brand);
            product.show();         // 小米牌电脑
            System.out.println("------------------");
    
            brand = new HuaWeiBrand();
            product = new PhoneProduct(brand);
            product.show();         // 华为牌手机
            System.out.println("------------------");
    
            product = new ComputerProduct(brand);
            product.show();         // 华为牌电脑
            System.out.println("------------------");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    运行效果如下:

    在这里插入图片描述

    10.3 桥接模式的优缺点

    • 优点:

      • 1)通过利用组合/聚合的关系来代替继承关系,提高了系统的扩展性,可维护性
      • 2)符合开闭原则
      • 3)符合合成复用原则
    • 缺点:

      • 1)需要用户正确识别系统中两个独立的纬度变化,提高了系统的复杂性
  • 相关阅读:
    web前端大作业:旅游网页主题网站设计——武汉旅游网页设计(11页)HTML+CSS+JavaScript
    访问控制列表配置实验
    mysql运行报错:
    如何在edge浏览器中给PDF添加文字批注
    UWB工业现场数字化管理
    JAVA获取30天或某段范围日期的方法
    国庆day5
    【Java】Spring Cloud OAuth2之密码模式实战
    一、C#—概述环境安装(1)
    linux 监控CPU利用率
  • 原文地址:https://blog.csdn.net/Bb15070047748/article/details/126368463