一、概念准备

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

  • 类的功能层次结构:假设现在有一个类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();
}
}

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();
}
}

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();
}

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("+");
}
}

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无需任何修改)。

一天一个设计模式——Bridge桥接模式的更多相关文章

  1. C++设计模式-Bridge桥接模式

    作用:将抽象部份与它的实现部份分离,使它们都可以独立地变化. 将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式 ...

  2. 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)

    原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...

  3. 设计模式07: Bridge 桥接模式(结构型模式)

    Bridge 桥接模式(结构型模式) 抽象与实现 抽象不应该依赖于实现细节,实现细节应该依赖于抽象. 抽象B稳定,实现细节b变化 问题在于如果抽象B由于固有的原因,本身并不稳定,也有可能变化,怎么办? ...

  4. Bridge桥接模式(设计模式11)

    在没有使用桥接模式: 扩展新问题(类归属膨胀问题) 1增加性的电脑类型,要增加每个品牌下面的类 2如果要增加一个新的电脑品牌,要增加美中电脑类型的类 违背单一职责原则: · 一个类:联想笔记本,有两个 ...

  5. Bridge桥接模式(结构型模式)

    现有一个需求,一个游戏系统需要构建不同风格的房屋,暂不考虑其他设计模式,需要能实现在PC端.移动端....等等多个平台的构建.最简单的实现方式如下: /// <summary> /// 房 ...

  6. java面试题之----jdbc中使用的设计模式(桥接模式)

    1.JDBC(JavaDatabase Connectivity) JDBC是以统一方式访问数据库的API. 它提供了独立于平台的数据库访问,也就是说,有了JDBC API,我们就不必为访问Oracl ...

  7. php设计模式之桥接模式

    php设计模式之桥接模式 一.概述 桥接模式:将两个原本不相关的类结合在一起,然后利用两个类中的方法和属性,输出一份新的结果. 其实就是讲不相关的东西通过类(本例中是SendInfo)结合在一起,从而 ...

  8. java设计模式之-----桥接模式

    一.概念定义 将抽象部分和实现部分分离,使他们都可以独立的变化.(这句话有点抽象啊..) 在软件系统中,某种类型由于自身逻辑,具有多个维度的变化,如何利用面向对象的技术来使得该类型沿着多方向变化,而又 ...

  9. java设计模式7——桥接模式

    java设计模式7--桥接模式 1.桥接模式介绍 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化.它是一种对象结构型模式,又称为柄体模式或接口模式. 2.解决问题 2.1.将复杂的组合 ...

随机推荐

  1. vue 加载静态图片

    <img class="headImg" :src="require('../../assets/uploads/'+headImg)" alt=&quo ...

  2. solus linux 更新源

    添加源(清华大学开源软件镜像)sudo eopkg ar Solus https://mirrors.tuna.tsinghua.edu.cn/solus/shannon/eopkg-index.xm ...

  3. 开源DDD设计模式框架YMNNetCoreFrameWork第一篇

    DDD设计模式:仓储.领域模型.应用层.聚合根.事件总线,以业务模型驱动设计,从数据模型驱动脱离,不用关心数据库设计,开发效率更高 DDD领域驱动设计模型概念不再讲解,直接上技术 框架搭建: 如图所示 ...

  4. Oracle delete 之后恢复数据

    当我们粗心大意直接delete from不加条件而又没有回滚的时候有一个很简单的方法能够将数据恢复到delete之前的状态 第一种方案已经帮助我解决了实际问题.第二种方案暂未实践 在此记录下以便日后查 ...

  5. Java 文件

    章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...

  6. NO11 SSH故障排查思路和netstat命令

    本章知识相关考试:1.企业场景面试题:Linux系统如何优化?2.企业场景面试题:SSH服务连不上,如何排查?记住回答技巧: 1 ping  2 telnet 客户端ssh工具:SecureCRT,x ...

  7. 【剑指Offer】面试题32 - III. 从上到下打印二叉树 III

    题目 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推. 例如: 给定二叉树: [3,9,20,nu ...

  8. 关于安装openfiler

    简介 Openfiler 由rPath Linux驱动,它是一个基于浏览器的免费网络存储管理实用程序,可以在单一框架中提供基于文件的网络连接存储 (NAS) 和基于块的存储区域网 (SAN).Open ...

  9. springBoot (适合ssm)

    很多小白在学ssm的时候,选用idea,网上应该有很多教程,创建maven项目,创建spring项目的都有,五花八门. 最近接触了springBoot,这个项目类型适用于ssm,还不用去创建很多文件夹 ...

  10. 关于如何实现一个Saga分布式事务框架的思考

    关于Saga模式的介绍,已经有一篇文章介绍的很清楚了,链接在这里:分布式事务:Saga模式. 关于TCC模式的介绍,也已经有一篇文章介绍的很清楚了,链接在这里:关于如何实现一个TCC分布式事务框架的一 ...