4.2 桥接模式
**1.定义:**将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
2.结构:
-
抽象化角色 :定义抽象类,并包含一个对实现化对象的引用。
-
扩展抽象化角色 :是抽象化角色的子类,实现父类中的业务方法, 并通过组合关系调用实现化角色中的业务方法。
-
实现化角色 :定义实现化角色的接口,供扩展抽象化角色调用。
-
具体实现化角色 :给出实现化角色接口的具体实现。
3.原理分析:
- 桥接模式使用了开闭原则,里氏代换原则,依赖倒转原则。
- 脱耦:将抽象化与实现化直接的耦合解脱开,将它们之间的强关联转化为弱关联,将两个角色之间的继承关系转化为关联关系。
抽象化:对象的共同属性抽出来形成的类
实现化:针对抽象化给出具体的实现
4.代码模板:
public interface Implementor {
public void operationImpl();
}
public abstract class Abstraction {
protected Implementor implementor;
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
public class RefindedAbstraction extends Abstraction {
@Override
public void operation() {
implementor.operationImpl();
}
}
5.案例说明:
- 类图:
- Java代码实现
抽象类:对OS视频进行扩展
public abstract class OSVersion {
protected VideoFile videoFile;
public void setVideoFile(VideoFile videoFile) {
this.videoFile = videoFile;
}
public abstract void play(String fileName);
}
抽象类实现:
public class LinuxVersion extends OSVersion{
@Override
public void play(String fileName) {
videoFile.decode("Linux", fileName);
}
}
public class WindowsVersion extends OSVersion{
@Override
public void play(String fileName) {
videoFile.decode("Windows", fileName);
}
}
实现类接口:进行视频播放格式的扩展
public interface VideoFile {
public void decode(String osType, String fileName);
}
具体的实现类:
public class MPEGFile implements VideoFile{
@Override
public void decode(String osType, String fileName) {
System.out.println("位于" + osType + "操作系统的" + fileName + ".MPEG文件进行播放");
}
}
public class WMVFile implements VideoFile{
@Override
public void decode(String osType, String fileName) {
System.out.println("位于" + osType + "操作系统的" + fileName + ".WMV文件进行播放");
}
}
Main函数
public class Main {
public static void main(String[] args) {
WMVFile wmvFile = new WMVFile();
WindowsVersion windowsVersion = new WindowsVersion();
windowsVersion.setVideoFile(wmvFile);
windowsVersion.play("刺客五六七");
MPEGFile mpegFile = new MPEGFile();
LinuxVersion linuxVersion = new LinuxVersion();
linuxVersion.setVideoFile(mpegFile);
linuxVersion.play("喜羊羊与灰太狼");
}
}
6.桥接模式的优点
-
实现了对抽象和实现之间的解耦
-
优化了类直接多继承的
-
桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。
-
实现细节对客户透明,可以对用户隐藏抽象细节
-
(缺点)难以识别要区分的两个独立变化的维度
7.桥接模式的使用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
8.桥接模式应用
- Java应用程序通过虚拟机对其底层指令集抽象,针对不同的OS平台依赖不同的虚拟机实现跨平台
- JDBC驱动程序是抽象,各个数据库是实现类型
9.桥接模式的拓展
在使用关联关系是,及在抽象类引入实现类接口时可能会出现不适配的情况,这是可以用适配器类型将其转换成抽象类可以适配的类进行关联。