概述
桥接模式也称为桥梁模式,是结构型设计模式之一.桥接,见其名知其义,主要起到一个桥梁的作用,连接着桥梁两边.这个两边具体指的是什么呢?我们来看一下桥接模式的定义
定义
将抽象部分与实现部分分离,使他们都可以独立的进行变化.
从模式的定义上来看,我们可以知道,这里的桥梁指的就是连接
抽象类
与实现类
之间的桥梁,这样他们就可以独立的变化
使用场景
- 多维度变化类或者说多个树状类之间的耦合都可以使用桥接模式来实现解耦
- 如果一个系统需要在构建的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次间建立静态的继承关系,即可以使用桥接模式
- 不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展
UML
其中涉及到的角色有
- Abstraction : 抽象部分,保持一个对实现部分对象的引用,抽象部分中的方法需要调用实现部分的对象来实现,该类一般为抽象类
- RefinedAbstraction : 优化的抽象部分,抽象部分的具体实现,对抽象部分的方法进行完善和扩展
- Implementor : 实现部分,可以是接口或抽象类,其方法不一定要与抽象部分抽象部分中的一致.
- ConcreteImplementorA/ConcreteImplementorB : 实现部分的具体实现,完善实现部分中方法定义的具体逻辑
- Client : 客户类,客户端程序.
实例
这里模拟一个煮咖啡的例子,假设这里提供了四种咖啡,大杯加糖,大杯原味,小杯加糖,小杯原味,相
首先定义Abstraction
public abstract class Coffee {
protected CoffeeAdditives impl;
public Coffee(CoffeeAdditives _impl) {
impl = _impl;
}
public abstract void makeCoffee();
}
- Implementor
public abstract class CoffeeAdditives {
public abstract String addSomething();
}
- ConcreteImplementor
public class Sugar extends CoffeeAdditives {
@Override public String addSomething() {
return "加糖";
}
}
public class Ordinary extends CoffeeAdditives {
@Override public String addSomething() {
return "原味";
}
}
- RefinedAbstraction
public class LargeCoffee extends Coffee {
private static final String TAG = "LargeCoffee";
public LargeCoffee(CoffeeAdditives _impl) {
super(_impl);
}
@Override public void makeCoffee() {
Log.d(TAG, "makeCoffee: --> 大杯的"+impl.addSomething()+"咖啡");
}
}
public class SmallCoffee extends Coffee {
private static final String TAG = "SmallCoffee";
public SmallCoffee(CoffeeAdditives _impl) {
super(_impl);
}
@Override public void makeCoffee() {
Log.d(TAG, "makeCoffee: -->小杯的"+impl.addSomething()+"咖啡");
}
}
- 客户端调用
Ordinary ordinary = new Ordinary();
Sugar sugar = new Sugar();
LargeCoffee largeCoffee = new LargeCoffee(ordinary);
largeCoffee.makeCoffee();
SmallCoffee smallCoffee = new SmallCoffee(ordinary);
smallCoffee.makeCoffee();
LargeCoffee largeCoffee1 = new LargeCoffee(sugar);
largeCoffee1.makeCoffee();
SmallCoffee smallCoffee1 = new SmallCoffee(sugar);
smallCoffee1.makeCoffee();
优缺点
优点
- 分离抽象与实现,灵活的扩展性以及对客户端透明的实现
缺点
- 不容易设计,是不是需要分离,如何分离等问题,需要一个恰到好处的分寸.