设计模式(9):桥接模式

「尺有所短,寸有所长;不忘初心,方得始终。」

一、桥接模式是什么

「桥接模式是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。桥接模式通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦,使得二者可以独立变化。」

桥接模式重点是将「抽象化 (Abstraction) 与 实现化 (Implementation) 解耦」

  • 「抽象化」 :抽象化就是忽略一些信息,把拥有共同性质的不同实体抽取出来形成类的过程即为抽象化的过程。

  • 「实现化」 :是对抽象化事物给出的具体实现 ,实现化产生的对象比抽象化更具体。

  • 「解耦」 :将抽象化和实现化之间的耦合分离开(强关联改换成弱关联),将两个角色之间的继承关系改为关联关系 。

    桥接模式中的解耦就是「在抽象化和实现化之间使用关联关系(组合或者聚合关系)而不是继承关系」,从而使两者可以相对独立地变化。

二、桥接模式的适用场景

  • 需要在抽象化角色和具体化角色之间增加更多的灵活性时,避免静态的继承联系,可以通过桥接模式在抽象层建立一个关联关系。

  • 对客户完全隐藏抽象的实现部分

  • 因为「继承或因为多层次继承」导致系统类的个数急剧增加的系统,可以使用桥接模式。

  • 一个类存在两个或两个以上独立变化的维度,且这两个维度都需要进行扩展,可以使用桥接模式。

    比如:红色三角形,红色圆形,蓝色三角形,蓝色圆形,这里的「颜色和形状就是两个不同的维度」,当颜色和形状都需要扩展时,例如增加黑色正方形,此时可以使用桥接模式。

设计模式(9):桥接模式

三、桥接模式结构

  • 「抽象类(Abstraction)」:提供高层控制逻辑的抽象类,「并依赖一个于完成底层实际工作的实现对象Implementor(实现类接口)(Abstraction与Implementor的关联关系)」,与Implementor之间具有关联关系,既可以包含抽象业务方法,也可以包含具体业务方法。
  • 「精确抽象类(Refined Abstraction)」:提供控制逻辑的变体。继承抽象类(Abstraction), 实现了在Abstraction中声明的抽象业务方法,可以调用在Implementor中定义的业务方法。(可以没有这个)
  • 「实现类接口(Implementor)」「所有具体实现声明通用接口」。可以和Abstraction的接口完全不同,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做组合聚合等复杂的操作。
  • 「具体实现类(Concrete Implementor)」:实现Implementor接口,提供基本操作的不同实现。
  • 「客户端 (Client)」:仅关心如何与抽象部分合作。客户端需要将抽象对象与一个实现对象连接起来。
设计模式(9):桥接模式

四、桥接模式实现方式

  • 明确类中独立的维度,分别为各个维度定义接口类,声明行为动作。
  • 为所有维度创建实现类, 实现接口中发具体方法。
  • 定义抽象接口,提供高层控制逻辑的抽象类
  • 在抽象类中添加指向实现类型的引用成员变量。抽象部分会将大部分工作委派给该成员变量所指向的实现对象。
  • 如果高层逻辑有多个变体, 则可通过扩展抽象基类为每个变体创建一个精确抽象(可以没有这个)
  • 客户端代码必须将实现对象传递给抽象部分的构造函数才能使其能够相互关联。

五、桥接模式的实现

案例:已颜色和形状组装成:红色三角形,红色圆形,蓝色三角形,蓝色圆形

5.1 不使用桥接模式的实现

在不使用桥接模式的实现,我们想得到红色三角形,红色圆形,蓝色三角形,蓝色圆形这四种类型就需要创建4个实现类,当添加一种其他颜色黄色时我们就需要再实现黄色三角形,黄色圆形,新增图形时也是如此,「当我们有3中颜色,10中图形时,我们就需要30个实现类,非常不易于扩展与解耦」。代码实现比较简单就不写了

5.2 使用桥接模式的实现

「桥接模式使用对象见的组合关系解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化」。通过客户端进行关联,客户端需要什么就关联什么,「非常灵活」

  • 「实现类接口(Implementor)」 :颜色接口

    /**
    * 颜色接口
    */

    public interface Colour {
    String coloring();
    }

  • 「具体实现类(Concrete Implementor)」 :实现颜色接口,红色,蓝色

    /**
    * 红色颜料
    */

    public class Red implements Colour {
    @Override
    public String coloring() {
    return "this is Red ";
    }
    }

    /**
    * 蓝色颜料
    */

    public class Blue implements Colour {
    @Override
    public String coloring() {
    return "this is blue ";
    }
    }
  • 「抽象类(Abstraction)」 图形抽象类,持有一个颜色Implementor的引用

    /**
    * 图形抽象类
    */

    public abstract class Shape {

    /**
    * 持有一个颜色Implementor的引用
    */

    protected Colour colour;

    public Shape(Colour colour){
    this.colour = colour;
    }

    /**
    * 图形着色
    */

    public abstract void graphicsColoring();

    }
  • 「精确抽象类(Refined Abstraction)」(具体的图形)

    /**
    * 圆形
    */

    public class Round extends Shape {

    public Round(Colour colour){
    super(colour);
    }

    @Override
    public void graphicsColoring() {
    String coloring = super.colour.coloring();
    System.out.println(coloring + "圆形");
    }
    }

    /**
    * 三角形
    */

    public class Triangle extends Shape {

    public Triangle(Colour colour){
    super(colour);
    }

    @Override
    public void graphicsColoring() {
    String coloring = super.colour.coloring();
    System.out.println(coloring + "三角形");
    }
    }
  • 「客户端代码实现」

    public static void main(String[] args) throws Exception {
    Triangle triangle = new Triangle(new Red());
    triangle.graphicsColoring();

    Round round = new Round(new Blue());
    round.graphicsColoring();
    }
  • 「案例结果输出」

设计模式(9):桥接模式

六、桥接模式的优缺点

「优点:」

  • 「开闭原则」。新增抽象部分和实现部分, 且它们之间不会相互影响。
  • 「单一职责原则」。抽象部分专注于处理高层逻辑, 实现部分处理平台细节。
  • 客户端代码仅与高层抽象部分进行交互, 不会接触到产品的详细信息,实现了解耦。

「缺点:」

  • 对高内聚的类使用该模式可能会让代码更加复杂。

  • 桥接模式使用范围具有一定的局限性,「要求正确识别出两个独立变化的维度」

七、桥接模式与其他模式的区别

  • 「抽象工厂(Abstract Factory)」

    可以用来创建和配置一个特定的Bridge模式。

  • 「适配器模式」

    用来帮助无关的类协同工作,它通常在系统设计完成后才会被使用。而Bridge模式是在系统开始时就被使用,它使得抽象接口和实现部分可以独立进行改变。

  • 「装饰模式」

    装饰模式和桥接模式在一定程度上都是为了减少子类的数目,避免出现复杂的继承关系。但是实现不同

    • 「装饰模式把子类中比基类中多出来的部分放到单独的类里面」,以适应新功能增加的需要,通过j将新功能的类封装到基类的对象中实现多功能组合
    • 「桥接模式把基类的实现化细节进行抽象」,在构造方法中把原来的基类进行抽象化,实现系统在多个维度上的独立变化 。

八、总结

Bridge 模式是一个结构型的模式,实现比较复杂,它很好的融入了「开闭原则」「单一职责原则」。避免了继承的强关联,使得不同维度可以独立开来,使得客户端与具体实现高度解耦。

原文始发于微信公众号(星河之码):设计模式(9):桥接模式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/27170.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!