设计模式--桥接模式详解

桥接模式(bridge pattern)

  • 桥接模式时将抽象部分 与它的实现部分 分离,使他们可以独立的变化。它是一种对象结构型模式, 又称为柄体 (Handle and Body)模式或者接口(interface)模式(组合

    以前使用的多层继承结构,耦合性太强,且违反了单一职责原则,如下图

如果以这种结构去设计程序的架构的话,拓展性会有很大的问题。

比如如果想增加一个新的电脑品牌,需要写三个类,如果想增加一个电子产品,依旧要写三个类,非常繁琐,

违反了单一职责原则:每个类只负责一个东西,每个类只有一个功能。

而从上图看出,每一个类的最终实现类都负责了不止一个事务,如联想台式:联想是品牌,而台式是电脑的品种。每个类拆分的不够彻底

分析:这个场景有两个变化的维度:品牌,类型

这里面的每个节点就是上面结构图中的最终实现类。

将结构看成这样,那我们在新增品牌的时候,只需要在x轴增加就好了,在新增类型的时候,只需要在y轴增加就好了,只要想办法通过一个链接点把它连起来,就可以形成一个新的产品。

而这,就是桥接模式,

我们需要将原来的事物高度抽象,只要超过两个场景变换维度的事物,就将其抽象出来,这个类型写一个抽象类,品牌写一个抽象类,通过一座桥将其连接起来,就可以构建产品

使用桥接模式来重写该事务

首先创建品牌接口,

java 复制代码
 package com.lyc.bridge;
 // 品牌,抽象类或者接口
 public interface Brand {
     void info();
 }

再写品牌实现类

java 复制代码
 package com.lyc.bridge;
 //联想品牌
 public class Lenovo implements Brand{
     @Override
     public void info() {
         System.out.print("联想品牌");
     }
 }
java 复制代码
 package com.lyc.bridge;
 //苹果品牌
 public class Apple implements Brand{
     @Override
     public void info() {
         System.out.print("Apple");
     }
 }

开始写电脑桥接类,在类中建立连接品牌的桥(即定义品牌属性,再写品牌构造器,在写电脑实现类的时候,无需再连接品牌类)这样大大减少了这两个事物的耦合度。

java 复制代码
 package com.lyc.bridge;
 //抽象的电脑类
 //桥接类 用于将电脑与品牌进行关联
 public  class Computer {
     //组合,品牌 桥接模式,桥用于链接,与适配器模式不同
     protected Brand brand; //子类在使用的时候可以随意设置品牌
     public Computer(Brand brand){
         this.brand = brand;
     }
     public void info(){
         //自带品牌
         brand.info();
     }
 }

再写电脑实现类

java 复制代码
 package com.lyc.bridge;
 ​
 public class Laptop extends Computer{
     public Laptop(Brand brand) {
         super(brand);
     }
 ​
     @Override
     public void info() {
         super.info();
         System.out.print("笔记本");
     }
 }
java 复制代码
 package com.lyc.bridge;
 ​
 public class Desktop extends Computer{
     public Desktop(Brand brand) {
         super(brand);
     }
     public void info()
     {
         super.info();
         System.out.print("台式机");
     }
 }

最后进行测试:

java 复制代码
 package com.lyc.bridge;
 ​
 public class Test {
     public static void main(String[] args) {
         //苹果笔记本
         Computer computer = new Laptop(new Apple());
         computer.info();
          System.out.println("");
         //联盟台式机
         Desktop desktop = new Desktop(new Lenovo());
         desktop.info();
     }
 }

效果:

这样就品牌与类型相互分离了

注意事项:

  1. 抽象部分与实现部分需要分离,不能有过多的耦合

  2. 桥接模式适用于多个维度的变化,如果维度较少,使用继承更加简单

  3. 桥接模式会增加系统复杂度,谨慎使用

类图:

桥接模式

  • 好处分析:

    • 桥接模式偶尔类似于多继承方案,但是多继承方案违背了类的单一职责原则,复用性较差,类的个数也非常多,桥接模式是比多继承方案更好的解决方法,极大地减少了子类的个数,从而降低管理和维护的成本

    • 桥接模式提高了系统的可扩容性,在两个变化维度任意扩展一个维度,都不需要修改原有模式,符合开闭原则,就像一座桥,可以把两个变化的维度连接起来。

  • 缺点分析:

    • 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程

    • 桥接模式要求正确识别出系统中两个独立变化的维度,因此适用范围具有一定的局限性

  • 最佳实践

    • 如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,可以通过桥接模式使他们在抽象层建立一个关联关系,抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以将动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,及系统需要对抽象化角色和现实化角色进行动态耦合

    • 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展

    • 虽然在系统中使用扩展是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计需求需要独立管理这两者,对于那些不希望使用继承或者因为多层次继承导致系统类的个数急速增加的系统,桥接模式非常适合

  • 使用实例

    • Java语言通过Java虚拟机实现了平台的无关性

    • AWT中的Peer架构:在同一个页面中,在window中与在Liunx中的画面不一致,代码一致,效果不同

    • JDBC驱动程序也是桥接模式的应用之一,JDBC本身就是一个抽象角色,他可以连接MySQL,也可以链接Oracle,与具体实现的角色进行分离

拓展:桥接模式+适配器模式?

桥接模式可以用在系统创建之初,就是类似于两个相关维度,如果在后面添加和前两个基本无关的维度,可以使用适配器模式将其连接起来。

我们应该将前面学习过的设计模式,尝试将其应用到自身代码中,加强理解!

希望对大家有所帮助!

相关推荐
触底反弹19 分钟前
🤯 面试被问 AI Workflow 和 Agent 有啥区别?3 张图 + 2 段代码讲清楚!
人工智能·设计模式·面试
杨充21 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充21 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充21 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充21 小时前
2.面向对象的特性
设计模式
杨充21 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充21 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充21 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法