003-结构型-05-桥接模式(Bridge)
一、概述
将抽象部分与它的具体实现部分分离。使它们都可以独立地变化。通过组合的方式建立两个类之间联系,而不是继承。
Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。
它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了。
1.1、适用场景
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
一个类存在两个(或多个)独立变化的维度。且这两个(或多个)维度都需要独立进行扩展
虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
不希望使用继承,或因为多层继承导致系统类的个数剧增
1.2、优缺点
优点:
- 分离抽象部分及其具体实现部分
- 提高了系统的可扩展性
- 符合开闭原则,可动态的切换实现
- 符合合成复用原则,实现细节对客户端透明,可以对用户隐藏实现细节
缺点:
- 增加了系统的理解与设计难度
- 需要正确地识别出系统中两个独立变化的维度
对比其他模式
桥接模式和组合模式
- 组合模式强调的是部分和整体间的组合,桥接模式强调的是平行级别上,不同类的组合
桥接模式和适配器模式
- 适配器模式改变已有的接口,桥接模式分离抽象和具体
1.3、类图角色及其职责

桥接模式的角色和职责
1、Client:Bridge模式的使用者
2、Abstraction(Car)
(1)抽象类接口(接口或抽象类)
(2)维护对行为实现(Implementor)的引用
3、Refined Abstraction(Bus、Suv):Abstraction子类
4、Implementor(Engine): 行为实现类接口 (Abstraction接口定义了基于Implementor接口的更高层次的操作)
5、ConcreteImplementor(OilEngine、ElectricityEngine):Implementor子类
抽象画

接口定义
public interface Sourceable {
public void method();
}
分别定义两个实现类:
public class SourceSub1 implements Sourceable {
@Override
public void method() {
System.out.println("this is the first sub!");
}
}
public class SourceSub2 implements Sourceable {
@Override
public void method() {
System.out.println("this is the second sub!");
}
}
定义一个桥,持有Sourceable的一个实例:
public abstract class Bridge {
private Sourceable source;
public void method(){
source.method();
}
public Sourceable getSource() {
return source;
}
public void setSource(Sourceable source) {
this.source = source;
}
}
public class MyBridge extends Bridge {
public void method(){
getSource().method();
}
}
测试
public class BridgeTest {
public static void main(String[] args) {
Bridge bridge = new MyBridge();
/*调用第一个对象*/
Sourceable source1 = new SourceSub1();
bridge.setSource(source1);
bridge.method();
/*调用第二个对象*/
Sourceable source2 = new SourceSub2();
bridge.setSource(source2);
bridge.method();
}
}
1.4、演进过程
举个例子,我们都知道,汽车有不同的发动机,有油的,有电的,还有用天然气的
我们先举两个不采用桥接模式的例子,通过对比,来看出桥接模式的优势
示例一、
项目代码:https://github.com/bjlhx15/patterns.git 中的patterns-base 中 structure/bridge/process01
基础接口
/*
* 汽车
*/
public interface Car {
//安装引擎
void installEngine();
}
先新建以下基础结构

运行测试
@Test
public void test() {
Car car = new OilBus();
car.installEngine();
}
查看类图结构

可以看到,一种车每增加一种发动机就要增加一个子类,到了后期,子类会越来越多,越来越庞大。这种方法不推荐使用。
示例二、
项目代码:https://github.com/bjlhx15/patterns.git 中的patterns-base 中 structure/bridge/process02
把所有的发动机都定义到Car接口中,每种车实现一次就好了
/*
* 汽车
*/
public interface Car {
//安装燃油引擎
public void installOilEngine();
//安装电动引擎
public void installElectricityEngine();
}
测试
@Test
public void test(){
Car bus = new Bus();
Car suv = new Suv(); bus.installOilEngine();
bus.installElectricityEngine(); suv.installOilEngine();
suv.installElectricityEngine();
}
UML图

这种方式就没有那么多子类了,每种车只有一个实现类,但是这种方法不符合我们的开放封闭原则,每增加一种发动机,就要修改Car接口,并修改所有实现类。这种方法肯定也是不推荐的。
示例三、桥接模式
项目代码:https://github.com/bjlhx15/patterns.git 中的patterns-base 中 structure/bridge/impl
创建发动机接口
/*
* 发动机
*/
public interface Engine {
public void installEngine();
}
以及车抽象类
/*
* 汽车
*/
public abstract class Car {
private Engine engine; public Car(Engine engine){
this.engine = engine;
} //安装发动机
public abstract void installEngine(); public Engine getEngine() {
return engine;
} public void setEngine(Engine engine) {
this.engine = engine;
}
}
基础类

UML类图

测试
@Test
public void getEngine() {
Engine oilEngine = new OilEngine();
Engine electricityEngine = new ElectricityEngine(); Car oilBus = new Bus(oilEngine);
Car electricityBus = new Bus(electricityEngine); Car oilSuv = new Suv(oilEngine);
Car electricitySuv = new Suv(electricityEngine); oilBus.installEngine();
electricityBus.installEngine(); oilSuv.installEngine();
electricitySuv.installEngine();
}
二、扩展
2.1、JDK中实现的桥接模式
1、 java.sql.Driver、java.sql.DriverManager与java.sql.DriverInfo
mysql的Driver、oracle的Driver就是桥接模式的实现部分。

2、DriverManager与DriverInfo(也就是Driver)实现了桥接模式
003-结构型-05-桥接模式(Bridge)的更多相关文章
- 【设计模式】结构型04桥接模式(Bridge Pattern)
学习地址:http://www.runoob.com/design-pattern/bridge-pattern.html 桥接模式(Bridge Pattern) 桥接模式(Bridge patte ...
- 【设计模式】结构型05组合模式(Composite Pattern)
组合模式(Composite Pattern) 意图:将对象组合成树形结构以表示"部分-整体"的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性. 主要解决:它在我们 ...
- 【设计模式】桥接模式 Bridge Pattern
开篇还是引用吕振宇老师的那篇经典的文章<设计模式随笔-蜡笔与毛笔的故事>.这个真是太经典了,没有比这个例子能更好的阐明桥接模式了,这里我就直接盗来用了. 现在市面上卖的蜡笔很多,各种型号, ...
- python 设计模式之桥接模式 Bridge Pattern
#写在前面 前面写了那么设计模式了,有没有觉得有些模式之间很类似,甚至感觉作用重叠了,模式并不是完全隔离和独立的,有的模式内部其实用到了其他模式的技术,但是又有自己的创新点,如果一味地认为每个模式都是 ...
- 桥接模式(Bridge、Implementor)(具体不同平台日志记录,抽象与实现分离)
桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化.它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式 ...
- 桥接模式(Bridge Pattern)
1,定义 桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...
- c#桥接模式(bridge结构模式)
桥接模式(bridge结构模式)c#简单例子 在前面的玩家中每增加一个行为,就必须在每个玩家中都增加,通过桥接模式将行为提取出来了,减少变化 ? 1 2 3 4 5 6 7 8 9 10 11 12 ...
- 【结构型】Flyweight模式
享元模式的主要目的.意图是为对象的大量使用提供一种共享机制.该模式的思想重在复用.共享复用.像文字.列表中的格子等这类多数都是需要考虑复用技术,否则必将大量耗费内存空间而使资源以及性能等大量耗费.该模 ...
- 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern)
原文:乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 桥接模式(Bridge Pattern) 作者:webabcd 介绍 ...
- 桥接模式-Bridge(Java实现)
桥接模式-Bridge 桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦, 将"类的功能层次结构" 与 "类的实 ...
随机推荐
- 02 c++的封装性 (构造和析构)
封装性: 关键字:public private protected 破坏封装:友元函数 friend 实现数据的隐藏:class类 默认是私有,结构体默认是公有. 类和对象:(定义类的注意事项) 在类 ...
- 织梦CMS5.7主动推送二次开发
今天一个朋友叫我写个织梦的百度主动推送插件,实现的功能是:每发表或者更新一篇文章,都会触动主动推送,达到资源最新提交给百度进行抓取. 案例站点:奇迹私服 第一步:登入FTP,在/后台的文件夹/arti ...
- Handling skewed data---Error metrics for skewed(偏斜的) classes(precision&recall)
skewed classes skewed classes: 一种类里面的数量远远高于(或低于)另一个类,即两个极端的情况. 预测cancer的分类模型,如果在test set上只有1%的分类误差的话 ...
- tomcat绑定项目classes路径
在Host中加入如下内容: <Context path="" docBase="D:\svn\MainSource\WebRoot" debug=&quo ...
- maven基础整理
转载:https://www.cnblogs.com/hzg110/p/6936101.html maven官网:http://maven.apache.org/index.html 一.为什么使用M ...
- maven的使用和环境搭建
请在博客分类的未分类中找到这篇文章
- 集合(Collection)类
集合(Collection)类是专门用于数据存储和检索的类.这些类提供了对栈(stack).队列(queue).列表(list)和哈希表(hash table)的支持.大多数集合类实现了相同的接口. ...
- Error Permission denied when running brew cleanup
Error Permission denied when running brew cleanup When I try to run `brew cleanup` I get: Warning: S ...
- Kafka ISR and AR HW 、 LEO
相信大家已经对 kafka 的基本概念已经有一定的了解了,下面直接来分析一下 ISR 和 AR 的概念. 0|1ISR and AR 简单来说,分区中的所有副本统称为 AR (Assigned Rep ...
- learning java AWT 布局管理器CardLayout
import javax.swing.*; import java.awt.*; import java.awt.event.ActionListener; public class CardLayo ...