桥接模式(Bridge)
意图
将抽象部分与他的实现部分分离,使他们可以独立地变化
也可以理解为:实现系统可以从多个维度分类,桥接模式将各个维度抽象出来,各个维度独立变化,之后通过聚合,将各个维度组合起来,减少各维度的耦合
适用性
1、你不希望在抽象和他的实现部分有一个固定的绑定关系,例如,在程序运行时,你希望他的实现部分可以被选择或者切换
2、类的抽象以及他的实现都应该可以通过生成子类的办法加以扩充
3、对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译
结构
Abstraction
定义抽象类的接口
维护一个只想Implementor类型对象的指针
RefinedAbstraction
扩充由Abstraction定义的接口
Implementor
定义实现类的接口,该接口不一定要与Abstraction的接口完全一致;事实上,这两个接口可以完全不同,一般来讲,Implementor接口仅提供基本操作,而Abstraction则定义了基于这些基本操作的较高层次的操作
ConcreteImplementor
实现Implementor接口并实现其方法
解决的问题
比如现在有一个抽象的Car类,一个维度,我们有几种具体的车的品牌,每种品牌的车都有几个具体的车,另外一个维度,车子又分为自动挡和手动挡,那么我们如果要创建一个新的车,就必须要创建一个具体的类,往上要一层层的继承,并且功能和其他的具体的类也有重复。
那么我们是否可以这样来桥接呢?我们把车品牌和变速器分开为两个维度,两个维度独立变化。
实现
Abstration
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:40
*/
public abstract class AbstractCar {
protected Transmission transmission;
public abstract void run();
public void setTransmission(Transmission transmission) {
this.transmission = transmission;
}
}
RefinedAbstraction
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:45
*/
public class BenzCar extends AbstractCar {
@Override
public void run() {
transmission.gear();
System.out.println("奔驰来了");
}
}
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:45
*/
public class FerrariCar extends AbstractCar {
@Override
public void run() {
transmission.gear();
System.out.println("Ferrari430来了");
}
}
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:45
*/
public class McLarenCar extends AbstractCar {
@Override
public void run() {
transmission.gear();
System.out.println("McLaren来了");
}
}
Implementor
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:42
*/
public abstract class Transmission {
public abstract void gear();
}
ConcreteImplementor
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:44
*/
public class ManualTransmission extends Transmission {
@Override
public void gear() {
System.out.println("手动挡汽车");
}
}
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:44
*/
public class AutoTransmission extends Transmission {
@Override
public void gear() {
System.out.println("自动挡汽车");
}
}
通过聚合,实现不同品牌不同变速器的汽车
package bridge;
/**
* @Author fitz.bai
* @Date 2018/8/29 14:48
*/
public class Client {
public static void main(String[] args) {
Transmission autoTran = new AutoTransmission();
AbstractCar benz = new BenzCar();
benz.setTransmission(autoTran);
benz.run();
Transmission manualTran = new ManualTransmission();
AbstractCar ferrari = new FerrariCar();
ferrari.setTransmission(manualTran);
ferrari.run();
}
}
/**
自动挡汽车奔驰来了
手动挡汽车Ferrari430来了
*/
优点
1、分离接口及其实现部分
2、提高可扩充性
3、实现细节对客户透明