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-手机产品:
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 "手机";
    }
}
  • 具体抽象角色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 "电脑";
    }
}
  • 实现角色-品牌:
package com.dfbz.demo01;

/**
 * @author lscl
 * @version 1.0
 * @intro:  实现角色
 */
public interface Brand {
    String getBrand();
}
  • 具体实现角色1-小米品牌:
package com.dfbz.demo01;

/**
 * @author lscl
 * @version 1.0
 * @intro: 具体实现角色
 */
public class XiaoMiBrand implements Brand {
    @Override
    public String getBrand() {
        return "小米";
    }
}
  • 具体实现角色2-华为品牌:
package com.dfbz.demo01;

/**
 * @author lscl
 * @version 1.0
 * @intro: 具体实现角色
 */
public class HuaWeiBrand implements Brand {
    @Override
    public String getBrand() {
        return "华为";
    }
}
  • 测试类:
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("------------------");

    }
}

运行效果如下:

在这里插入图片描述

10.3 桥接模式的优缺点

  • 优点:

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

    • 1)需要用户正确识别系统中两个独立的纬度变化,提高了系统的复杂性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

緑水長流*z

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

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

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

打赏作者

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

抵扣说明:

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

余额充值