java设计模式-----14、桥接模式
Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
举个例子,我们都知道,汽车有不同的发动机,有油的,有电的,还有用天然气的
我们先举两个不采用桥接模式的例子,通过对比,来看出桥接模式的优势
第一个:
先新建一个接口Car,所有车都实现这个接口,这个接口中有一个公共的方法installEngine()安装发动机
/*
* 汽车
*/
public interface Car {
//安装引擎
public void installEngine();
}
然后,不同的车,比如公交,suv,轿车,都有不同的发动机,所以先新建不同的车,实现Car接口,因为不同种类的车下面还有不同的发动机,所以将具体的车建为抽象类,将其中实现Car的方法也抽象化。
公交
/*
* 公交车
*/
public abstract class Bus implements Car{ @Override
public abstract void installEngine();
}
SUV
/*
* SUV
*/
public abstract class Suv implements Car{ @Override
public abstract void installEngine();
}
不同的车有不同的发动机,每种车的不同发动机都是一个子类
public class OilBus extends Bus{
@Override
public void installEngine() {
System.out.println("给公交安装燃油发动机");
}
}
public class ElectricityBus extends Bus{
@Override
public void installEngine() {
System.out.println("给公交安装电动发动机");
}
}
public class OilSuv extends Suv{
@Override
public void installEngine() {
System.out.println("给SUV安装燃油发动机");
}
}
public class ElectricitySuv extends Suv{
@Override
public void installEngine() {
System.out.println("给SUV安装电动发动机");
}
}
运行客户端
public class MainClass {
public static void main(String[] args) {
Car car = new OilBus();
car.installEngine();
}
}
可以看到这样的结果

但是这样有个很大的弊端

可以看到,一种车每增加一种发动机就要增加一个子类,到了后期,子类会越来越多,越来越庞大。这种方法不推荐使用。
第二个例子:
把所有的发动机都定义到Car接口中,每种车实现一次就好了
Car
/*
* 汽车
*/
public interface Car {
//安装燃油引擎
public void installOilEngine();
//安装电动引擎
public void installElectricityEngine();
}
Bus
/*
* 公交车
*/
public class Bus implements Car{
@Override
public void installOilEngine() {
System.out.println("给公交安装燃油发动机");
} @Override
public void installElectricityEngine() {
System.out.println("给公交安装电动发动机");
}
}
Suv
/*
* SUV
*/
public class Suv implements Car{
@Override
public void installOilEngine() {
System.out.println("给SUV安装燃油发动机");
} @Override
public void installElectricityEngine() {
System.out.println("给SUV安装电动发动机");
}
}
客户端
public class MainClass {
public static void main(String[] args) {
Car bus = new Bus();
Car suv = new Suv();
bus.installOilEngine();
bus.installElectricityEngine();
suv.installOilEngine();
suv.installElectricityEngine();
}
}
运行结果

这种方式就没有那么多子类了,每种车只有一个实现类,但是这种方法不符合我们的开放封闭原则,每增加一种发动机,就要修改Car接口,并修改所有实现类。这种方法肯定也是不推荐的。
接下来,就要说到桥接模式了。
桥接模式的概念:Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展。
把抽象与行为实现分开,保证各部分的独立性,所以我们可以把车和发动机分离开来,保证他们各自的独立性。

增加一种车,对发动机没有影响,增加发动机吧对车也没有影响,Car接口中有对Engine的引用,也就是Car体系与Engine体系之间的桥梁。

桥接模式的角色和职责
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 Engine {
public void installEngine();
}
/*
* 燃油发动机
*/
public class OilEngine implements Engine{
@Override
public void installEngine() {
System.out.println("安装燃油发动机");
}
}
/*
* 电动发动机
*/
public class ElectricityEngine implements Engine{
@Override
public void installEngine() {
System.out.println("安装电动发动机");
}
}
新建Car体系
/*
* 汽车
*/
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;
}
}
/*
* 公交车
*/
public class Bus extends Car{ public Bus(Engine engine) {
super(engine);
} @Override
public void installEngine() {
System.out.print("公交:");
this.getEngine().installEngine();
}
}
/*
* SUV
*/
public class Suv extends Car{
public Suv(Engine engine) {
super(engine);
} @Override
public void installEngine() {
System.out.print("SUV:");
this.getEngine().installEngine();
}
}
最后,新建客户端调用
public class MainClass {
public static void main(String[] args) {
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();
}
}
结果如下

可以看到,这样子的话,新建这的种类,丝毫不影响发动机,新建一种发动机,也不影响车,这就是一个简单的桥接模式的例子
总结:
1.桥接模式的优点
(1)实现了抽象和实现部分的分离
桥接模式分离了抽象部分和实现部分,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,分别定义接口,这有助于系统进行分层设计,从而产生更好的结构化系统。对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了。
(2)更好的可扩展性
由于桥接模式把抽象部分和实现部分分离了,从而分别定义接口,这就使得抽象部分和实现部分可以分别独立扩展,而不会相互影响,大大的提供了系统的可扩展性。
(3)可动态的切换实现
由于桥接模式实现了抽象和实现的分离,所以在实现桥接模式时,就可以实现动态的选择和使用具体的实现。
(4)实现细节对客户端透明,可以对用户隐藏实现细节。
2.桥接模式的缺点
(1)桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。
(2)桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围有一定的局限性。
3.桥接模式的使用场景
(1)如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
(2)抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
(3)一个类存在两个独立变化的维度,且这两个维度都需要进行扩展。
(4)虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
(5)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用
java设计模式-----14、桥接模式的更多相关文章
- java设计模式7——桥接模式
java设计模式7--桥接模式 1.桥接模式介绍 桥接模式是将抽象部分与它的实现部分分离,使他们都可以独立的变化.它是一种对象结构型模式,又称为柄体模式或接口模式. 2.解决问题 2.1.将复杂的组合 ...
- java设计模式之桥接模式
桥接模式 桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化.这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦.这种模式涉及到一个作为桥接的 ...
- Java设计模式:桥接模式
问题提出 生活中有很多事物集合,设为A1,A2......Am ,而每个事物都有功能F1,F2....Fn. 例如邮局的发送业务.简单模拟有两类事物:信件和包裹,均有平邮和挂号邮寄功能.程序设计中如何 ...
- 再起航,我的学习笔记之JavaScript设计模式14(桥接模式)
桥接模式 桥接模式(Bridge): 在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦 从定义上看桥接模式的定义十分难以理解,那么我们来通过示例来演示什么是桥接模式. 现在我们需要做一个导航 ...
- Java设计模式应用——桥接模式
性能管理系统中,数据产生后需要经过采集,汇聚,入库三个流程,用户才能查询使用. 采集可以是snmp采集,也可以是ems采集:汇聚可以使storm汇聚,也可以是spark汇聚:入库可以是hdfs入库,也 ...
- java设计模式之-----桥接模式
一.概念定义 将抽象部分和实现部分分离,使他们都可以独立的变化.(这句话有点抽象啊..) 在软件系统中,某种类型由于自身逻辑,具有多个维度的变化,如何利用面向对象的技术来使得该类型沿着多方向变化,而又 ...
- JAVA设计模式之桥接模式(bridge)
桥接模式: 分离抽象与具体实现,让他们可以独自发展,防止类爆炸 场景: 过年走亲戚是我们中国人传统的习俗,走亲戚那就少不了要买东西(苹果,牛奶等等),这些具体的东西就是具体的类 蒙牛牛奶,有机苹果,有 ...
- 八戒转世投胎竟然是Java设计模式:桥接模式
目录 示例 代码实例 桥接模式 定义 意图 主要解决问题 何时使用 优缺点 八戒转世投胎的故事 示例 请开发一个画图程序,可以画各种颜色不同形状的图形,请用面向对象的思 想设计图形 分析: 1.比如有 ...
- java面试题之----jdbc中使用的设计模式(桥接模式)
1.JDBC(JavaDatabase Connectivity) JDBC是以统一方式访问数据库的API. 它提供了独立于平台的数据库访问,也就是说,有了JDBC API,我们就不必为访问Oracl ...
- java设计模式3--单例模式(Singleton)
本文地址:http://www.cnblogs.com/archimedes/p/java-singleton-pattern.html,转载请注明源地址. 单例模式 保证一个类仅有一个实例,并提供一 ...
随机推荐
- kindeditor编辑器修改文本后保存时发现获取到的内容还是修改前的文本内容
定义kindeditor的时候要加上一下几个属性设置: KindEditor.ready(function(K) { var editor = K.create("textarea[name ...
- Mongodb基础与入门
一:基本了解 1. 特点 基于分布式文件存储的NoSql数据库.能为WEB应用提供可扩展的高性能数据存储解决方案. ...
- Egret学习笔记 (Egret打飞机-8.敌机和主角飞机发射子弹)
经过前面几章的准备,我们差不多已经具备了一个基本的框架,这一章我们就开始添砖加瓦了. 敌机定时发射一个子弹,子弹的方向是从上到下,但是发射子弹的代码应该放在哪儿呢? 从面向对象编程的思想来说,子弹是敌 ...
- hdu1995 汉诺塔V
可以直接把前K-1个罗盘全部忽略了,因为移动前K-1个罗盘不会影响第K个. 也就是相当于只移动剩下的n-k-1个罗盘,当只移动第k个罗盘时,f(k)=1;当要哟东第k个和第k+1个时,就必须先把第k个 ...
- 压缩tar命令
option z表示压缩,所以才有后面的.gz, c表示创建这个压缩包,v是可视,能看到其打包和压缩的过程,f表示文件 zcvf 命令格式为 先压缩后跟压缩的目录 tar zcvf /home/xia ...
- 网络基础Cisco路由交换一
VLAN概述 Virtual LAN(虚拟局域网)是物理设备上链接的不受物理位置限制的用户的一个逻辑组,. 引用VLAN: 交换机分割了冲突域,但是不能分割广播域,随着交换机端口数量的增多,网络中广播 ...
- (三十一)java多线程二
因为线程在执行的过程中具有一定的不确定性,在并发的时候就会出现安全问题,因此一般需要采取一定的措施来保证线程的安全,同步代码块就是其中一种方式. 以下是模拟银行取钱的多线程小例子,两个都能确保安全,但 ...
- JavaScript禁止浏览器默认行为
JavaScript禁止浏览器默认行为 1.实现源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...
- Linux显示更新十次后退出
Linux显示更新十次后退出 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ top -n 10 top - 19:19:21 up 48 min, 2 use ...
- E: 未发现软件包 install_flash_player_11_linux.x86_64.tar.gz
1 错误描述 youhaidong@youhaidong:~$ sudo apt-get install install_flash_player_11_linux.x86_64.tar.gz 正在读 ...