桥接模式

75 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

一、介绍

1.1 桥接模式(Builder)

桥接,顾名思义,就是用来连接两个部分,为被分离了的抽象部分和实现部分搭桥。 **官方一点的说明:**桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interfce)模式。

1.2 桥接模式的结构

桥梁模式所涉及的角色有:

  • 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
  • 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
  • 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
  • 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。

1.3 类图(维基百科

Bridge_UML_class_diagram.svg.png 来自:维基百科

1.4 使用场景

  • 如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
  • 一个类存在两个独立变化的维度,而这两个维度都需要进行扩展。

二、举例

2.1 问题引入

电脑特点分为可触屏和不可触屏,同时电脑又有那么多品牌。如果新增一个品牌或者新增一个特点,如何能让我们的代码写的更好,看起来更优雅那,这个时候就需要考虑桥接模式了

2.2 品牌 Brade

public interface Brade {
    //开机
    void open();
    //打电话;
    void internet();
    //关机;
    void close();
}

2.3 品牌实现类

package com.test.designpattern.bridge;

public class Mac implements Brade{
    @Override
    public void open() {
        System.out.println("Mac开机");
    }

    @Override
    public void internet() {
        System.out.println("Mac上网");
    }

    @Override
    public void close() {
        System.out.println("Mac关机");
    }
}
package com.test.designpattern.bridge;

public class Lenovo implements Brade{
    @Override
    public void open() {
        System.out.println("Lenovo开机");
    }

    @Override
    public void internet() {
        System.out.println("Lenovo上网");
    }

    @Override
    public void close() {
        System.out.println("Lenovo关机");
    }
}

2.4 抽象电脑 AbsComputer

package com.test.designpattern.bridge;

public abstract class AbsComputer {
    //聚合品牌;
    private Brade brade;

    public AbsComputer(Brade brade) {
        super();
        this.brade = brade;
    }

    //调用品牌的方法;
    protected void open(){
        this.brade.open();
    }

    protected void internet(){
        this.brade.internet();
    }

    protected void close(){
        this.brade.close();
    }

}

2.5 可触摸电脑和不可触摸电脑

package com.test.designpattern.bridge;

/**
 * 可触摸电脑
 */
public class TouchableComputer extends AbsComputer{

    public TouchableComputer(Brade brade) {
        super(brade);
    }

    public void open(){
        System.out.println("可触摸电脑");
        super.open();
    }

    public void internet(){
        System.out.println("可触摸电脑");
        super.internet();
    }

    public void  close(){
        System.out.println("可触摸电脑");
        super.close();
    }
}

package com.test.designpattern.bridge;

/**
 * 不可触摸电脑
 */
public class UntouchableComputer extends AbsComputer{
    public UntouchableComputer(Brade brade) {
        super(brade);
    }

    public void open(){
        System.out.println("不可触摸电脑");
        super.open();
    }

    public void internet(){
        System.out.println("不可触摸电脑");
        super.internet();
    }

    public void  close(){
        System.out.println("不可触摸电脑");
        super.close();
    }
}

2.6 客户端

package com.test.designpattern.bridge;

public class Client {
    public static void main(String[] args) {
        //选择可触摸mac操作
        AbsComputer mac=new TouchableComputer(new Mac());
        mac.open();
        mac.internet();
        mac.close();

        System.out.println("<------------------------------->");

        //使用可触摸Lenovo操作;
        AbsComputer lenovo = new TouchableComputer(new Lenovo());
        lenovo.open();
        lenovo.internet();
        lenovo.close();

        System.out.println("<------------------------------->");
        //选择不可触摸mac操作
        AbsComputer macUntouchable = new UntouchableComputer(new Mac());
        macUntouchable.open();
        macUntouchable.internet();
        macUntouchable.close();

        System.out.println("<------------------------------->");

    }
}

2.7 结果

可触摸电脑 Mac开机 可触摸电脑 Mac上网 可触摸电脑 Mac关机

<------------------------------->

可触摸电脑 Lenovo开机 可触摸电脑 Lenovo上网 可触摸电脑 Lenovo关机

<------------------------------->

不可触摸电脑 Mac开机 不可触摸电脑 Mac上网 不可触摸电脑 Mac关机

<------------------------------->

2.8 优缺点:

优点:

  • 桥接模式避免了多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
  • 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。

缺点:

  • 桥接模式的使用会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就针对抽象层进行设计与编程。
  • 桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性,如何正确识别两个独立维度也需要一定的经验积累。

三、参考

zh.m.wikipedia.org/wiki/%E6%A9… zhuanlan.zhihu.com/p/58903776 blog.csdn.net/MrTumnus/ar… www.bilibili.com/video/BV1G4…