桥接模式
定义
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and
Body)模式或接口(Interfce)模式。
使用场景
桥我们大家都熟悉,顾名思义就是用来将河的两岸联系起来的。而此处的桥是用来将两个独立的结构联系起来,而这两个被联系起来的结构可以独立的变化,所有其他的理解只要建立在这个层面上就会比较容易。
下面是一些官方的说明,
-
如果一个系统需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象层建立一个关联关系。
-
“抽象部分”和“实现部分”可以以继承的方式独立扩展而互不影响,在程序运行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对抽象化角色和实现化角色进行动态耦合。
-
一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立进行扩展
-
对于那些不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
优点:
- 分离抽象接口及其实现部分。桥接模式使用“对象间的关联关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,也就是说抽象和实现不再在同一个继承层次结构中,而是“子类化”它们,使它们各自都具有自己的子类,以便任何组合子类,从而获得多维度组合对象。
- 在很多情况下,桥接模式可以取代多层继承方案,多层继承方案违背了“单一职责原则”,复用性较差,且类的个数非常多,桥接模式是比多层继承方案更好的解决方法,它极大减少了子类的个数。
- 桥接模式提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统,符合“开闭原则”。
缺点:
- 增加了系统的理解与设计难度
- 需要正确地识别出系统中两个独立变化的维度
uml图
桥梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
场景
星巴克的咖啡有大杯中杯超大杯,口味有原味加奶加糖
分析当前业务场景,认为可以将咖啡的容量作为抽象化Abstraction,而咖啡口味为实现化Implementor
第一步:创建实现化部分的接口定义(咖啡口味的维度)
public interface ICoffeeAdditives {
void addSomething();
}
第二步:创建抽象化部分的接口定义(咖啡容量的维度)
//抽象化Abstraction
public abstract class Coffee {
protected ICoffeeAdditives additives;
public Coffee(ICoffeeAdditives additives){
this.additives=additives;
}
public abstract void orderCoffee(int count);
}
第三步:实现实现化部分(咖啡口味维度)的接口ICoffeeAdditives
//加奶
public class Milk implements ICoffeeAdditives {
@Override
public void addSomething() {
System.out.println("加奶");
}
}
//加糖
public class Sugar implements ICoffeeAdditives {
@Override
public void addSomething() {
System.out