引言
设计模式,即Design Patterns,是指在软件设计中,被反复使用的一种代码设计经验。使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性。
电脑是由硬件设备和软件系统组成,为了提升电脑的性能,用户经常会更换电脑硬件或者重装系统,而不是选择置换一台新的电脑(创建新类)。所以这就要求电脑和硬件设备、操作系统分离,可以独立变化,这种替换符合桥接模式的特点。
定义
结构型模式
用于把抽象化与实现化解耦,使得二者可以独立变化
桥接模式是对类的扩展性设计,它是用组合关系替代继承,从而降低了抽象和实现的耦合度。
模式结构
1. 抽象化角色(Abstraction)
定义抽象类,包含一个对实现化对象的引用,表明期望什么样的接口(功能)
2. 扩展抽象化角色(Refined Abstraction)
抽象化的实现,通过组合关系调用实现化角色中的业务方法
3. 实现化角色(Implementor)
定义实现类,包含抽象化需要的业务方法
4. 扩展实现化角色(Concrete Implementor)
实现化的实现,给出业务方法的具体实现
在前端开发中,没有创建接口的习惯。所以,不会去创建 抽象化角色
、实现化角色
,而只创建 扩展抽象化角色
、扩展实现化角色
。
图示:
说明:通过桥接模式,可以搭配出不同功能的模块来。
特点
优点
- 桥接模式符合开闭原则
- 桥接模式符合合成复用原则
- 桥接模式分离抽象与实现,更利于扩展
缺点
- 桥接模式是高阶设计,有一定的难度,依赖开发人员的技术水平。
实现
扩展抽象化角色
class Abstraction {
implementor;
constructor(implementor) {
this.implementor = implementor;
}
do() {
this.implementor.doSomething();
}
}
扩展实现化角色
class Implementor1 {
doSomething() {
console.log('这是Implementor1');
}
}
class Implementor2 {
doSomething() {
console.log('这是Implementor2');
}
}
使用
const implementor1 = new Implementor1();
const implementor2 = new Implementor2();
const abstraction1 = new Abstraction(implementor1);
const abstraction2 = new Abstraction(implementor2);
abstraction1.do();
abstraction2.do();
自由搭配,可以组成具备不同功能的模块。如果想要 扩展
功能,既可以选择开发新的 抽象化角色
,也可以选择开发新的 实现化角色
。例如:电脑和操作系统,系统不变,重新设计电脑硬件,就会出现不同的品牌;电脑不变,更换系统,会带来不同的使用体验。
举例
桥接模式模拟电脑和操作系统
分析:电脑(Computer)是抽象化角色,操作系统(System)是实现化角色。我们可以通过桥接模式来分离电脑和操作系统,
电脑
class Computer {
system;
constructor(system) {
this.system = system;
}
launch() {
this.system.launch();
}
}
系统
class WindowsSystem {
launch() {
console.log('windows 启动');
}
}
class LinuxSystem {
launch() {
console.log('linux 启动');
}
}
使用
const windows = new WindowsSystem();
const linux = new LinuxSystem();
const windowComputer = new Computer(windows);
const linuxComputer = new Computer(linux);
windowComputer.launch(); // windows电脑启动
linuxComputer.launch(); // linux电脑启动
应用场景
桥接模式应用的场景很普遍,凡事大大小小的系统,为了扩展性,都能看到桥接模式的影子。
这里就不一一列举了,凡是系统出现多维度的变化,都可以使用桥接模式来设计和开发。