桥接模式定义
桥接模式也被称为桥梁模式(Bridge Design Pattern),桥接模式定义:将抽象和实现脱耦,让他们可以独立变化
耦合关系可以分为强关联和弱关联,其中强关联是在编译期间关系就已经确定的,无法再运行期间动态的改变的关联,弱关联是可以动态确定的并且在运行期间可以动态改变的关联,java的继承属于强关联,聚合属于弱关联,脱耦是指使用聚合或者组合来取代继承来实现弱关联
桥接模式案例
设想我们需要绘制矩形,圆形,椭圆,正方形,我们至少需要4个形状类,但是如果需要绘制的图形需要不同的颜色,此时就有两种不同的方案
第一种方案是为每一种图形都提供一套各种颜色的版本
这种设计方案,颜色和图形紧密结合在一起,必须为每一种形状准备各种颜色的版本,假设我们现在需要再加入一种颜色,我们需要为每个图形添加一个子类去实现这种颜色
第二种方案是根据实际需要对形状和颜色进行组合
第二个方案中的两张图分别表示形状和颜色类之间的组合关系,下面的图表示的各个类之间的继承和组合关系,第二种方案需要为所有的图形声明一个共同的父类,为所有的颜色声明一个父类,我们需要的产品就是这两种产品组合得到的。
桥接模式的结构
这个具有一般桥接模式的类图,可以看出桥接模式分成了四个部分
- 抽象化角色:抽象化给出的定义,并保存一个对实现化对象的引用,就是图像类中的形状父类。
- 修正抽象化角色:扩展抽象化角色,改变和修正父类对抽象化的定义,比如形状下有正方形,圆形等图形。
- 实现化角色:这个角色给出具体角色的接口,但是不给出具体的实现,这个接口不一定和抽象化角色的接口定义相同,实际上两者可以完全不一样,好比形状的颜色接口。
- 具体实现化角色:这个角色给出实现化角色接口的具体实现,好比各种具体的颜色。
如果将Abstraction和Implementor看成两个岸边的话,那么聚合关系就像桥一样将他们连接起来,这就是这个模式为什么叫桥梁模式的原因。
代码实现
package structuralDesgin.bridgePattern;
/**
* @author cuckooYang
* @create 2020-08-05 15:39
* @description 画笔抽象类
**/
public abstract class BrushPenAbstraction {
/**
* 保留对颜色的引用
*/
protected ImplementorColor implementorColor;
/**
* 每种笔都有自己的实现
*/
public abstract void operationDraw();
public void setImplementorColor(ImplementorColor implementorColor){
this.implementorColor = implementorColor;
}
}
package structuralDesgin.bridgePattern;
/**
* @author cuckooYang
* @create 2020-08-05 15:42
* @description 粗毛笔的实现
**/
public class BigBrushPenRefinedAbstraction extends BrushPenAbstraction {
@Override
public void operationDraw() {
System.out.println("big and "+implementorColor.bepaint()+" drawing");
}
}
/**
* @author cuckooYang
* @create 2020-08-05 15:39
* @description 颜色抽象类
**/
public abstract class ImplementorColor {
public abstract String bepaint();
}
/**
* @author cuckooYang
* @create 2020-08-05 15:46
* @description 红色
**/
public class OncreteImplementorRed extends ImplementorColor {
@Override
public String bepaint() {
return "red";
}
}
桥接模式的优点
- 分离抽象接口及其实现部分
- 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统
- 实现细节对客户透明,可以对用户隐藏实现细节,它已经由抽象层通过聚合关系完成了封装
桥接模式的注意事项
桥接模式主要考虑如何拆分抽象和实现,桥接模式的意图是实现对变化的封装,尽量把可能变化的因素封装到最细,最小的逻辑单元中。
桥接模式的使用场景
-
不希望或不适用使用继承的场景:例如继承层次过度,无法更细化设计颗粒
-
接口或抽象类不稳定的场景
-
重用性要求较高的场景