1 基础知识

定义:将抽象部分与它的具体实现部分分离,使得它们都可以独立变化。特征:通过组合的方式建立两个之间的联系而不是继承。

使用场景:抽象和具体实现之间增加更多的灵活性;一个类存在两个(多个)独立变化的维度,且这两个(多个)维度需要独立扩展即抽象和具体实现独立扩展;不希望使用继承或因多层继承导致类爆炸。

优点:分离抽象部分及具体实现部分;提高了系统的可扩展性;符合开闭原则;符合合成复用原则。缺点:增加了系统的理解与设计难度;需要正确地识别出系统中两个独立变化的维度。

2 代码示例

使用场景:银行有许多如农业银行、工商银行;银行中的账号类型有定期、活期等。银行和账号之间可以通过组合实现多种场景。

账号接口:

public interface Account {
Account openAccount();
void showAccountType();
}

账号接口的实现:定期账号  DepositAccount

public class DepositAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打开定期账号");
return new DepositAccount();
} @Override
public void showAccountType() {
System.out.println("这是一个定期账号");
}
}

账号接口的实现:活期账号

public class SavingAccount implements Account {
@Override
public Account openAccount() {
System.out.println("打开活期账号");
//可以添加自己特有的代码
return new SavingAccount();
} @Override
public void showAccountType() {
System.out.println("这是一个活期账号");
}
}

抽象银行类:

public abstract class Bank {
protected Account account;
public Bank(Account account){
this.account = account;
}
//抽象的方法名字不一定要与Account中的相同
abstract Account openAccount();
}

具体银行类:

public class ABCBank extends Bank {
public ABCBank(Account account) {
super(account);
} @Override
Account openAccount() {
System.out.println("打开中国农业银行账号");
     //委托 
account.openAccount();
return account;
}
}
public class ICBCBank extends Bank {
public ICBCBank(Account account) {
super(account);
} @Override
Account openAccount() {
System.out.println("打开中国工商银行账号");
     //委托
account.openAccount();
return account;
}
}

至此其类关系图可以清楚的体现如何桥接的:

Account就是一座桥梁,使具体账户类与抽象的银行间进行组合,银行和账号之间可以进行独立的发展。在具体银行类时一定要有一个委托行为的方法,不要让银行去打开账号。

应用层:

public class Test {
public static void main(String[] args) { Bank icbcBank = new ICBCBank(new DepositAccount());
Account icbcAccount = icbcBank.openAccount();
icbcAccount.showAccountType(); Bank icbcBank2 = new ICBCBank(new SavingAccount());
Account icbcAccount2 = icbcBank2.openAccount();
icbcAccount2.showAccountType(); Bank abcBank = new ABCBank(new SavingAccount());
Account abcAccount = abcBank.openAccount();
abcAccount.showAccountType();
}
}

3 相关模式

(1)桥接模式和状态模式

由于从模式结构上看,状态模式和策略模式是一样的,因此这两个模式的关系也基本上类似于桥接模式和策略模式的关系。只不过状态模式的目的是封装状态对应的行为,并在内部状态改变的时候改变对象的行为。

(2)桥接模式和模板方法模式

这两个模式有相似之处。虽然标准的模板方法模式是采用继承来实现的,但是模板方法也可以通过回调接口的方式来实现。如果把接口的实现独立出去,那就类似于模板方法通过口去调用具体的实现方法了,这样的结构就和简化的桥接模式类似了。

可以使用桥接模式来模拟实现模板方法模式的功能。如果在实现 Abstraction对象的时候,在其中定义方法,方法中就是某个固定的算法骨架,也就是说这个方法就相当于模板方法。在模板方法模式中,是把不能确定实现的步骤延迟到子类去实现;现在在桥接模式中,把不能确定实现的步骤委托给具体实现部分去完成,通过回调实现部分的接口,来完成算法骨架中的某些步骤。这样一来,就可以实现使用桥接模式来模拟实现模板方法模式的功能。使用桥接模式来模拟实现模板方法模式的功能,还有一个潜在的好处,就是模板方法也可以很方便地扩展和变化。在标准的模板方法中,一个问题就是当模板发生变化的时候,所有的子类都要变化,非常不方便。而使用桥接模式来实现类似的功能,就没有这个问题。

注:另外,这里只是说从实现具体的业务功能上,桥接模式可以模探实现意模板方法棋式能实现的功能,并不是说桥接模式和模板方法模式就变成一样的,或者是桥接模式就可以替换模板方法模式了。要注意它们本身的功能、目的、本质思想都是不一样的。

(3)桥接模式和抽象工厂模式

这两个模式可以组合使用。桥接模式中,抽象部分需要获取相应的实现部分的接口对象,那么谁来创建实现部分的具体实现对象呢?这就是抽象工厂模式派上用场的地方。也就是使用抽象工厂模式来创建和配置一个特定的具体的实现对象。事实上,抽象工厂主要是用来创建一系列对象的,如果创建的对象很少,或者是很简单,还可以采用简单工厂,也能达到同样的效果,但是会比抽象工厂来得简单。

(4)桥接模式和适配器模式

这两个模式可以组合使用。这两个模式功能是完全不一样的,适配器模式的功能主要是用来帮助无关的类协同工作,重点在解决原本由于接口不兼容而不能一起工作的那些类,使得它们可以一起工作。而桥接模式则重点在分离抽象部分和实现部分所以在使用上,通常在系统设计完成以后,才会考虑使用适配器模式;而桥接模式是在系统开始的时候就要考虑使用。虽然功能上不一样,这两个模式还是可以组合使用的,比如,已有实现部分的接口,但是有些不太适应现在新的功能对接口的需要,完全抛弃吧,功能还用得上,该怎么办呢?那就使用适配器来进行适配,使得旧的接口能够适应新的功能的需要。

0

桥接模式(Bridge)---结构型的更多相关文章

  1. 桥接模式 桥梁模式 bridge 结构型 设计模式(十二)

      桥接模式Bridge   Bridge 意为桥梁,桥接模式的作用就像桥梁一样,用于把两件事物连接起来   意图 将抽象部分与他的实现部分进行分离,使得他们都可以独立的发展.  意图解析 依赖倒置原 ...

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

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

  3. Java设计模式13:常用设计模式之桥接模式(结构型模式)

    1. Java之桥接模式(Bridge Pattern) (1)概述: 首先我们说一个生活中的例子:       就拿汽车在路上行驶的来说.即有小汽车又有公共汽车,它们都不但能在市区中的公路上行驶,也 ...

  4. 跟着实例学习设计模式(9)-桥接模式bridge(结构型)

    桥接模式属于结构型设计模式. 设计意图:将抽象部分与实现部分分离.使它们都能够独立的变化. 一看到设计意图,大家可能有些发懵,我们看到的继承和接口不都是抽象和实现分离的吗?尤其是接口和抽象类都是这种实 ...

  5. 设计模式 笔记 桥接模式 Bridge

    //---------------------------15/04/15---------------------------- //Bridge 桥接模式----对象结构型模式 /* 1:意图:将 ...

  6. 【设计模式】桥接模式 Bridge Pattern

    开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...

  7. python 设计模式之桥接模式 Bridge Pattern

    #写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...

  8. 桥接模式(Bridge、Implementor)(具体不同平台日志记录,抽象与实现分离)

    桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式 ...

  9. 设计模式10: Facade 外观模式(结构型模式)

    Facade 外观模式(结构型模式) 系统的复杂度 假设我们要开发一个坦克模式系统用于模拟坦克车在各种作战环境中的行为,其中坦克系统由引擎.控制器.车轮.车身等各个子系统构成. internal cl ...

  10. 组合模式/composite模式/对象结构型模式

    组合模式/composite模式/对象结构型 意图 将对象组合成树形结构以表示"整体--部分"的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 动机 C ...

随机推荐

  1. Codeforces Round #590 (Div. 3) Editorial

    Codeforces Round #590 (Div. 3) Editorial 题目链接 官方题解 不要因为走得太远,就忘记为什么出发! Problem A 题目大意:商店有n件商品,每件商品有不同 ...

  2. LeetCode. 计数质数

    题目要求: 统计所有小于非负整数 n 的质数的数量. 示例i: 输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 . 代码: class Soluti ...

  3. idea中创建的go项目,添加project sdk时没有go sdk选项的解决方式

    同样是后端开发,年薪50万和年薪20万的差距在哪里>>> 更新: 为了防止你被我这个流水账气到,先看这个结论吧:这个问题的结局方法:忽略,没有什么影响. -------------- ...

  4. MyBatis 源码篇-日志模块2

    上一章的案例,配置日志级别为 debug,执行一个简单的查询操作,会将 JDBC 操作打印出来.本章通过 MyBatis 日志部分源码分析它是如何实现日志打印的. 在 MyBatis 的日志模块中有一 ...

  5. 怎样退出mysql命令行

    使用: mysql -u root -p 进入 mysql 命令号以后, 如果想退出, 可以使用: quit 命令, 如下: mysql -u root -p quit;

  6. CCF - CCSP 2018-01 绝地求生 BFS

    BFS从安全地区方向搞一下就好了 1.还是注意每回合清空 2.posx居然开小了,可不能犯这种错误 3.地图用a和节点的dis重名了,建议其他变量禁止用a命名 4.在输入数据之前continue了,这 ...

  7. Java 8 Collectors 类的静态工厂方法

    摘自<<Java 8 实战>> Collectors 类的静态工厂方法 工厂方法 返回类型 用于 toList List<T>  把流中所有项目收集到一个 List ...

  8. mysql 5.7.19安装

    从mysql官网下载的mysql5.7.19免安装版, 安装时出现问题,mysql总是启动不起来,在网上查了下资料,做个记录: .将mysql解压到指定的文件夹 .以管理员身份运行cmd .定位到my ...

  9. python之如何爬取一篇小说的第一章内容

    现在网上有很多小说网站,但其实,有一些小说网站是没有自己的资源的,那么这些资源是从哪里来的呢?当然是“偷取”别人的数据咯.现在的问题就是,该怎么去爬取别人的资源呢,这里便从简单的开始,爬取一篇小说的第 ...

  10. caffe prototxt分析

    测试用prototxt name: "CIFAR10_quick"layer { name: "data" type: "MemoryData&quo ...