桥接模式(结构)
简介
桥接模式(BridgePattern)是一种结构型设计模式,通过将抽象部分与实现部分分离,把多种可匹配的使用进行组合,从而能在开发时分别使用。
分离抽象实现: 将抽象部分与它的具体实现部分分离,使它们都可以独立的变化;独立的变化就是在一定程度上进行解耦
组合方式: 通过组合的方式建立两个类之间的联系,而不是继承;
桥接模式 相当于使用桥梁将两侧连接起来,这里指的是使用桥梁连接两个类,在两个类之间建立某种联系,可以通过继承,也可以通过组合,桥接模式是采用组合的方式,建立两个类之间的关系;合成复用原则,推荐优先使用组合,不是继承;桥接模式可以防止子类过多,成系统复杂的情况;
桥接模式的重点是理解类的抽象部分和具体的实现部分
抽象过程: 抽象部分,经过抽象化,忽略某些信息,将不同的实体当做同一个对待;面向对象中,将对象的共同性质抽取出来,形成类的过程,就是抽象化过程;
实现过程: 对于具体实现的部分,也要进行实现化,针对抽象化,给出具体实现;这个过程就是实现过程,过程的产出就是具体实现部分,具体实现部分产生的对象,比抽象产生的更具体,是对抽象化事物的具体化产物;
应用场景
桥接模式适用场景:
抽象实现灵活:
抽象和具体实现之间,需要增加更多灵活性的情况下,适合使用桥接模式; 使用桥接模式,可以避免在这两个层次之间,建立静态的继承关系,通过桥接模式在二者之间建立关联关系; 抽象和实现都可以各自以继承的方式扩展,互不影响; 可以动态的将抽象的子类对象和实现的子类对象进行组合,在系统中,抽象和实现之间进行了解耦;
独立变化维度:
一个类存在两个或更多的独立变化维度,并且这些维度都需要独立扩展; 抽象部分可以独立扩展,具体实现的部分,也可以独立扩展;
不使用继承:不希望使用继承,或因多层继承导致系统类的个数增加;
优缺点
有点
分离抽象与实现:
分离抽象部分和具体实现部分; 桥接模式使用组合关系解耦了抽象和实现之间的继承关系; 抽象和实现可以格子沿着自己的维度进行扩展; 抽象和实现不在同一个继承层次中,通过进行组合,可以获得多维度的组合对象;
提高扩展型:
提高了系统的可扩展性; 解耦了抽象与实现,二者可以继续进行扩展,不需要改变系统原有的功能;
符合开闭原则;
符合合成复用原则;
缺点
系统复杂: 增加了系统的理解与设计难度;
识别变化维度: 需要正确地识别出系统中,两个独立变化的维度;
桥接模式的使用范围,有一定的局限性;
相关设计模式的区别
桥接模式与组合模式:
组合模式更强调部分与整体间的组合; 桥接模式更强调平行级别上,不同类的组合;
桥接模式与适配器模式:
共同点: 都是让两个类配合工作;
不同点: 二者目的不同;
适配器模式 是改变已有接口,让二者之间相互配合;目的是配合; 桥接模式 分离抽象和具体的实现,目的是分离;
示例讲解
业务逻辑场景: 开发跨平台的视频播放器平台有Android,iOS,Windows,Linux,Mac,播放器支持的格式有MP4,AVI,RMVB,FLV格式;这种情况下,适合使用桥接模式;
平台: 播放器支持Linux,Android平台; 视频格式: 播放器支持MP4,FLV视频格式;
这里分为两块,一块是平台,一块是视频格式; 平台可以不断的扩展,如:Windows,iOS,MAC,嵌入式平台; 视频类型也可以不断的扩展,如:H264,H265,MPEG等; 二者可以随着自己的层级进行扩展;
视频格式抽象
public interface Vedio {
/**
* 打开视频
* 可以打开MP4/FLV格式视频
* 视频(格式)是个 抽象
* @return
*/
Vedio openVedio();
/**
* 查看视频信息
*/
void showVedio();
}
FLV视频格式实现
/**
* FLV视频格式
*/
public class FlvVedio implements Vedio {
@Override
public Vedio openVedio() {
System.out.println("打开FLV格式视频");
return new FlvVedio();
}
@Override
public void showVedio() {
System.out.println("当前视频格式是FLV");
}
}
MP4视频格式实现
/**
* MP4格式
*/
public class MP4Vedio implements Vedio {
@Override
public Vedio openVedio() {
System.out.println("打开MP4格式视频");
return new MP4Vedio();
}
@Override
public void showVedio() {
System.out.println("当前视频格式是MP4");
}
}
系统平台抽象
/**
* 平台操作系统 抽象类
*/
public abstract class Platform {
/**
* 这是桥接模式最核心的代码
* 在 Platform 中通过组合方式关联 Vedio
* Platform 的子类也可以关联 Vedio 子类
*/
protected Vedio account;
public Platform(Vedio account) {
this.account = account;
}
/**
* 该方法与 Vedio 中的方法名相同
* 方法名相同不是强制的
* @return
*/
abstract Vedio openVedio();
}
Linux系统平台实现
public class LinuxPlatform extends Platform {
public LinuxPlatform(Vedio account) {
super(account);
}
@Override
Vedio openVedio() {
System.out.println("在Linux平台播放视频");
return account;
}
}
Android系统平台实现
public class AndroidPlatform extends Platform {
public AndroidPlatform(Vedio account) {
super(account);
}
@Override
Vedio openVedio() {
System.out.println("在Android平台打开视频");
return account;
}
}
客户端测试类
public class Main {
public static void main(String[] args) {
// 在Linux平台打开FLV视频
Platform linuxPlatform = new LinuxPlatform(new FlvVedio());
Vedio linuxFlv = linuxPlatform.openVedio();
linuxFlv.showVedio();
System.out.println();
// 在Android平台打开MP4视频
Platform androidPlatform = new AndroidPlatform(new MP4Vedio());
Vedio androidMp4 = androidPlatform.openVedio();
androidMp4.showVedio();
}
}
测试结果
在Linux平台播放视频
当前视频格式是FLV
在 Android 平台打开视频
当前视频格式是MP4
- 感谢你赐予我前进的力量