本文已参加【新人创作礼】活动,一起开启掘金创作之路。
毛笔和蜡笔
假如需要使用大、中、小3种型号的画笔来绘制12种不同的颜色。如果使用蜡笔,需要准备3×12=36支。但如果使用毛笔的话,只需要提供3种型号的毛笔,外加12个颜料盒即可,涉及的对象个数仅为3+12=15,远小于36,却能实现与36支蜡笔同样的功能。如果增加一种新型号的画笔,并且也需要具有12种颜色,相应地,蜡笔需增加12支,而毛笔只需增加一支。
通过分析可以得知:在蜡笔中,颜色和型号两个不同的变化维度(即两个不同的变化原因)耦合在一起,无论是对颜色进行扩展,还是对型号进行扩展,都势必会影响另一个维度。但在毛笔中,颜色和型号实现了分离,增加新的颜色或者型号对另一方都没有任何影响。如果使用软件工程中的术语,可以认为,在蜡笔中颜色和型号之间存在较强的耦合性,而毛笔很好地将二者解耦,使用起来非常灵活,扩展也更为方便。在软件开发中,也提供了一种设计模式来处理与画笔类似的具有多变化维度的情况,即将要介绍的桥接模式。
概念
桥接模式(Bridge Pattern):将抽象部分与其实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式。
角色
Abstraction:抽象类
RefinedAbstraction:扩充抽象类
Implementor:实现类接口,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多、更复杂的操作
ConcreteImplementor:具体实现类
实例代码
interface Implementor {
public void operationImpl();
}
abstract class Abstraction {
// 定义实现类接口对象
// 定义为Implementor为了方便其子类访问impl其中的方法
protected Implementor impl;
public void setImpl(Implementor impl) {
this.impl = impl;
}
public abstract void operation();
}
public RefinedAbstraction extends Abstraction {
public void operation() {
// 实现类方法
impl.operationImpl();
// 业务代码
}
}
总结
场景
(1)一个类存在多个独立的变化维度,例如蜡笔类,包含了画笔和颜料两个维度,拆分为毛笔和颜料。 (2)抽象部分和实现部分可以互不影响,各自通过继承的方式扩展。
优点
(1)分离抽象接口和其实现部分,抽象和实现可以沿着各自的维度进行变化 (2)桥接可以取代多层继承,减少子类数量,符合“单一职责原则”。 (3)桥接模式提高了系统的扩展性。两个维度变化,不需要修改原有系统,符合开闭原则
缺点
(1)增加系统理解和设计难度 (2)识别独立变化维度,需要一定的经验积累
参考材料
[1] 刘伟. 设计模式的艺术[M]. 清华大学出版社, 2020.