桥接设计模式
1、手机操作问题
现在对不同手机类型的不同品牌实现操作编程(比如:开机、关机、上网,打电话等)

【1】以上传统方式的缺点
1)扩展性问题(类爆炸),如果我们再增加手机样式(旋转式),就需要增加各个品牌手机的类,同样如果我们增加一个手机品牌,也要再各个手机样式类下增加。
2)违反了单一职责原则,当我们增加手机样式时,要同时增加所有品牌的手机,这样增加了代码维护成本。
3)解决方案-使用桥接模式。
2、桥接模式的结构
桥接(Bridge)模式包含了以下主要角色:
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
3、桥接模式——基本介绍
1)桥接模式(Bridge模式)是指:将实现与抽象放在两个不同的类层次中,使两个层次可以独立改变。它是使用组合关系代理继承关系来实现,从而降低了抽象和实现这两个可变维度。
2)是一种结构型设计模式
3)Bridge模式基于类的最小设计原则,通过使用封装、聚合及继承等行为让不同的类承担不同的职责。它的主要特点是把抽象(Abstraction)与行为实现(Implementation)分离开来,从而可以保持各部分的独立性以及应对他们的功能扩展。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| public interface Brand { void open(); void close(); void call(); }
public class XiaoMi implements Brand { @Override public void open() { System.out.println(" 小米手机开机"); } @Override public void close() { System.out.println(" 小米手机关机"); } @Override public void call() { System.out.println(" 小米手机打电话"); } }
public class Vivo implements Brand { @Override public void open() { System.out.println(" Vivo手机开机"); } @Override public void close() { System.out.println(" Vivo手机关机"); } @Override public void call() { System.out.println(" Vivo手机打电话"); } }
public abstract class Phone { private Brand brand; public Phone(Brand brand) { this.brand = brand; } protected void open() { this.brand.open(); } protected void close() { this.brand.close(); } protected void call() { this.brand.call(); } }
public class FoldedPhone extends Phone { public FoldedPhone(Brand brand) { super(brand); } public void open() { super.open(); System.out.println(" 折叠样式手机 "); } public void close() { super.close(); System.out.println(" 折叠样式手机 "); } public void call() { super.call(); System.out.println(" 折叠样式手机 "); } }
|
4)视频播放器案例
需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windos、Mac、Linux等)上播放多种格式的视频文件,常见的视频格式包括RMVB、AVI、WMV等。该播放器包含了两个维度,适合使用桥接模式。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public abstract class OperatingSystem { protected VideoFile videoFile; public OperatingSystem(VideoFile videoFile) { this.videoFile = videoFile; } public abstract void play(String fileName); }
public class Windows extends OperatingSystem { public Windows(VideoFile videoFile) { super(videoFile); } @Override public void play(String fileName) { super.videoFile.decode(fileName); } }
public class Mac extends OperatingSystem { public Mac(VideoFile videoFile) { super(videoFile); } @Override public void play(String fileName) { super.videoFile.decode(fileName); } }
public interface VideoFile { void decode(String name); }
public class AVIFile implements VideoFile { @Override public void decode(String name) { System.out.println("avi视频文件:" + name); } }
public class RMVBFile implements VideoFile { @Override public void decode(String name) { System.out.println("rmvb视频文件:" + name); } }
|
4、桥接模式在JDBC中剖析
1)JDBC的Driver接口,如果从桥接模式来看,Driver就是一个接口,下面可以有MySQL的Driver,Oracle的Driver,这些就都可以当作实现接口类。
2)代码分析
4、桥接模式的注意事项及应用场景
【1】好处
【2】注意事项
1)实现了抽象和实现部分的分离,从而极大的提高了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
2)对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其他的部分由具体业务来完成。
3)桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
4)桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。
5)桥接模式要求正确识别出系统中两个独立变化的维度(抽象和实现),因此其使用范围有一定的局限性,即需要有这样的应用场景。
6)装饰者模式是主体与附加功能的解耦,桥接是抽象与具体的解耦。
【3】应用场景
1)对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
2)当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
3)当一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
4)常见的应用场景:
— JDBC驱动程序
— 银行转账系统
— — 转账分类:网上转账,柜台转账,ATM转账
— — 转账用户类型:普通用户,银卡用户,金卡用户
— 消息管理
— — 消息类型:即时消息,延时消息
— — 消息分类:手机短信,邮件消息,QQ消息…