目录
桥接模式
定义
桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
相关角色
Abstraction:抽象类
RefinedAbstraction:扩充抽象类
Implementor:实现类接口
ConcreteImplementor:具体实现类
解决问题
将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。
优点
- 分离抽象接口及其实现部分;
- 桥接模式有时类似于多继承方案,但是多继承方案违背了类的单一职责原则(即一个类只有一个变化的原因),复用性比较差,而且多继承结构中类的个数非常庞大,桥接模式是比多继承方案更好的解决方法;
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统;
- 实现细节对客户透明,可以对用户隐藏实现细节。
缺点
- 增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程;
- 要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一定的局限性。
使用场景
我们再来看看桥接模式的使用场景,在以下情况下应当使用桥接模式:
-
如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。
-
设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。
-
需要跨越多个平台的图形和窗口系统上。
-
一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
桥接模式结构视图
应用场景
如果需要开发一个跨平台视频播放器,可以在不同操作平台(Windows、Linux、UNIX等)播放多种格式的视频文件,如PMEG、RMVB、AVI、WMV等常见适配格式,现使用桥接模式设计播放器。
要求实现以下内容:
(1)绘制桥接模式结构视图
(2)给出实例类图并实现代码
实例类图
代码实现
package bridge;
public class AVIFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("操作系统:"+osType+"\n"+"文件名称:"+fileName);
}
}
package bridge;
public class Client {
public static void main(String args[]) {
VideoFile vf;
OperatingSystemVersion osType1 = new WindowsVersion();
vf = new AVIFile();
osType1.setVideo(vf);
osType1.play("AVI");
OperatingSystemVersion osType2 = new LinuxVersion();
vf = new AVIFile();
osType2.setVideo(vf);
osType2.play("WMV");
OperatingSystemVersion osType3 = new UnixVersion();
vf = new AVIFile();
osType3.setVideo(vf);
osType3.play("PMEG");
}
}
package bridge;
public class LinuxVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Linux播放";
this.vf.decode(osType,fileName);
}
}
package bridge;
public class MPEGFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("操作系统:"+osType+"文件名称:"+fileName);
}
}
package bridge;
public abstract class OperatingSystemVersion {
protected VideoFile vf;
public void setVideo(VideoFile vf) {
this.vf = vf;
}
public abstract void play(String fileName);
}
package bridge;
public class RMVBFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("操作系统:"+osType+"文件名称:"+fileName);
}
}
package bridge;
public class UnixVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Unix播放";
this.vf.decode(osType,fileName);
}
}
package bridge;
public interface VideoFile {
public void decode(String osType, String fileName);
}
package bridge;
public class WindowsVersion extends OperatingSystemVersion {
public void play(String fileName) {
String osType = "Windows播放";
this.vf.decode(osType,fileName);
}
}
package bridge;
public class WMVFile implements VideoFile {
public void decode(String osType, String fileName) {
System.out.println("操作系统:"+osType+"文件名称:"+fileName);
}