博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一天一个设计模式——Bridge桥接模式
阅读量:5019 次
发布时间:2019-06-12

本文共 3715 字,大约阅读时间需要 12 分钟。

一、概念准备

  在理解桥接模式之前,先要理解面向对象程序设计中的两个概念:

  • 类的功能层次结构:假设现在有一个类Something,这个类有一些成员属性和成员方法,但是现有的功能不能满足要求,因此我们想扩展这个类,给这个类创建一个子类SomethingBetter来继承它,并在子类中添加更多属性和方法。像这样不同的功能位于不同的类继承结构中,就构成了类的功能层次结构。
  • 类的实现层次结构:回顾一下抽象类的作用,抽象类声明抽象方法(定义了方法接口API),然后在继承它的子类中实现相关方法。由于我们将方法定义和实现分离到了不同的类中,从而实现了类的高可替换性,并有了模板Template Method方法模式。虽然这里也有父类和子类的继承关系,但是这里的继承并不是为了增加新功能,而是为了完成“定义——实现 分离”中的实现环节。这种层次结构就是类的实现层次接口。

二、模式说明

  如果类的设计都只有一层(程序中自定义的类不存在继承关系),这时候类的功能层次结构和实现层次结构是混杂在一起的,也很难扩展(无法确定应该继承哪个类来扩展功能,同一个方法如果想替换其实现也无法做到)。因此需要按照上面说的,将类的功能层次和实现层次分开,为了在分开后能继续保持一定的联系,这时候就需要一个桥梁,将它们连接起来。(Bridge也有桥梁的意思,连接两个事物)

三、代码示例

  在下面的桥接模式代码示例中,着重关注哪些时功能层次,哪些是实现层次,二者又是如何桥接起来的。

1、类的功能层次结构

Display类:Display类的功能是抽象的,负责“显示”一些东西,它位于功能层次结构的最上层。open、print、close这三个方法是Display类提供的接口,它们定义了显示的步骤,这三个方法调用的是Display实现类的对象。

package com.designpattern.cn.bridgepattern;public class Display {    private DisplayImpl impl;    public Display(DisplayImpl impl){        this.impl = impl;    }    public void open(){        impl.rawOpen();    }    public void print(){        impl.rawPrint();    }    public void close(){        impl.rawClose();    }    public final void display(){        open();        print();        close();    }}
View Code

CountDisplay类:CountDisplay类在Display类的基础上增加了一个新功能,具有“只显示规定次数”的功能。因此,这属于“类的功能层次范畴”。

package com.designpattern.cn.bridgepattern;public class CountDisplay extends Display {    public CountDisplay(DisplayImpl impl){        super(impl);    }    public void multiDisplay(int times){        open();        for(int i=0; i < times; i++){            print();        }        close();    }}
View Code

 

2、类的实现层次结构

DisplayImpl类:位于“类的实现层次结构”的最上层。DisplayImpl是抽象类,声明了rawOpen、rawPrint、rawClose三个抽象方法。

package com.designpattern.cn.bridgepattern;public abstract class DisplayImpl {    public abstract void rawOpen();    public abstract void rawPrint();    public abstract void rawClose();}
View Code

 

StringDisplayImpl类:它是仙子字符串的类,但它并不是直接显示字符串,而是继承了DisplayImpl类,作为子类来使用rawOpen、rawPrint、rawClose三个方法显示字符串。

package com.designpattern.cn.bridgepattern;public class StringDisplayImpl extends DisplayImpl {    private String string;    private int width;    public StringDisplayImpl(String string){        this.string = string;        this.width = string.getBytes().length;    }    @Override    public void rawOpen(){        printLine();    }    @Override    public void rawPrint(){        System.out.println("|" + string + "|");    }    @Override    public void rawClose() {        printLine();    }    private void printLine(){        System.out.print("+");        for(int i = 0; i < width; i++){            System.out.println("-");        }        System.out.println("+");    }}
View Code

 

3、Main类测试结果

 

四、模式类图

五、模式中的角色

  • Abstraction抽象化:类的功能层次的最上层,它使用Implementor角色的方法定义了基本功能,如上面的Display类。
  • RefinedAbstraction改善后的抽象化:增加了Abstraction的功能,如上面的CountDisplay类。
  • Implementor实现者:类的实现层次结构最上层,定义了用于实现Abstraction的角色的接口方法,如上面的DisplayImpl类。
  • ConcreteImplementor具体实现者:负责实现Implementor角色定义的接口方法,如上面的StringDisplayImpl类。

那么,这其中的桥梁Bridge是什么呢?对于示例程序,Display类和DisplayImpl是如何关联的,从程序中看出,这里的桥梁应该是impl字段。

六、相关的设计模式

  • 模板方法Template Method模式:模板方法模式就是使用了桥接模式中的类的实现层次结构。父类调用抽象方法,子类实现具体方法。
  • 抽象工厂Abstract Factory模式:可以使用抽象工厂设计出更好的ConcreteImplementor类。
  • 适配器Adapter模式:桥接模式连接了类的结构层次和实现层次,适配器模式则将功能类似,但是接口不匹配的类结合在一起。

七、扩展

  • 采用bridge桥接模式分离功能层次和实现层次,更有利于类的扩展,如果要增加功能,只需在功能层次这一侧做修改,无需调整实现层次,并且所有的实现层次都能利用增加的功能。
  • 继承是强关联,委托是弱关联。继承可以方便的得到功能更强的类,但是一旦使用继承,则在类之间形成了强关联关系,如果想改变或者替换其中的一个类,就必须修改类的代码。上面的例子中,使用了委托,只有当Display类的实例生成时,才作为参数,与被传入的类构成关联关系(示例程序中,只有Main类生成Display类和CountDisplay类的实例时,才将StringDisplayImpl类的实例作为参数传递给Display类和CountDisplay类)。除了StringDisplayImpl类,我们可以使用任意一个ConcreteImplementor角色传递给Display类和CountDisplay类,就能很容易的改变实现(只需修改Main类,Display类和DisplayImpl无需任何修改)。

转载于:https://www.cnblogs.com/zheng-hong-bo/p/11106278.html

你可能感兴趣的文章
Java中的国际化程序
查看>>
Ubuntu 安装LAMP
查看>>
合数转换为两个素数之和
查看>>
Visual Studio Code 使用 Typings 实现智能提示功能
查看>>
java-map复合类型(HashMap-TreeMap)常用操作例子(适合初学者)
查看>>
Spark记录-官网学习配置篇(一)
查看>>
Linux记录-salt分析
查看>>
Android Studio默认快捷键
查看>>
C# params关键字
查看>>
计算机如何储存浮点数
查看>>
发布开源库到JCenter所遇到的一些问题记录
查看>>
封装个 Android 的高斯模糊组件
查看>>
git shell 中文
查看>>
两个Map的对比,三种方法,将对比结果写入文件。
查看>>
这次不一样:八百年金融危机史(珍藏版)
查看>>
逻辑思维简易入门
查看>>
分析模式:可复用的对象模型
查看>>
软件创富密码:iPhone应用程序开发攻略之深入浅出Objective-C 2.0(双色)
查看>>
1.6捕获异常
查看>>
事务处理
查看>>