1. 桥接设计模式介绍
在软件系统中,某些类型由于自身的逻辑,它具有两个或多个维度的变化,可以采用桥接模式来应对这种“多维度变化”。
定义
将抽象部分与实现部分分离,使它们可以独立地进行变化。
2. 桥接设计模式使用场景
- 如果一个系统需要在构建的抽象化角色和具体角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
- 一个类存在两个独立变化的维度,并且这两个维度都需进行扩展。
3. 桥接设计模式UML类图
角色介绍
Abstraction:抽象部分。该类保持了一个对实现部分的引用,抽象部分中的方法需要调用实现部分的对象来实现,该类一般为抽象类
RefinedAbstraction:优化的抽象部分。 抽象部分的具体实现,该类一般是对抽象部分的方法进行完善和扩展。
Implementor:实现部分。 可以接口或抽象,该方法不一定要与抽象部分中的一致,一般情况下是由实现部分提供基本操作,而抽象部分定义的则是基于实现部分这些基本操作的业务方法。
ConcreteImplementorA/ConcreteImplementorB: 实现部分的具体实现。完善实现部分中方法定义的具体逻辑。
4. 桥接设计模式简单实现
模式代码如下:
- (1)、实现部分的抽象接口
public interface Implementor {
/**
* 实现抽象部分的具体方法
*/
public void operationImpl();
}
- (2)、实现部分具体实现
ConcreteImplementtorA:
public class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
//具体实现
}
}
ConcreteImplementtorB:
public class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
//具体实现
}
}
- (3)、抽象部分的实现
public abstract class Abstraction {
private Implementor mImplementor;
public Abstraction(Implementor implementor) {
this.mImplementor = implementor;
}
public void operation(){
mImplementor.operationImpl();
}
}
- (4)、抽象部分的子类
public class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void refinedOperation() {
//对Abstraction中的方法进行扩展
}
}
- (5)、客户端
public class Client {
public static void main(String[] args) {
//客户调用逻辑
}
}
以上只是模式代码,只是对UML类图的实现。
下面考虑一中情形:
有两种汽车:一般汽车和SUV汽车;每种汽车都可以安装不同的引擎,有两种引擎:大马力和小马力两种。
- (1)、首先定义引擎接口:
public abstract class Engine {
//速度
public abstract String speed();
}
引擎接口里面有一个抽象方法,要来表示不同的引擎不同的速度。
- (2)、具体的引擎实现类:
SmallEngine:
public class SmallEngine extends Engine {
@Override
public String speed() {
return "小马力引擎速度慢";
}
}
LargeEngine:
public class LargeEngine extends Engine {
@Override
public String speed() {
return "大马力引擎速度快";
}
}
- (3)、汽车抽象类:
public abstract class Car {
protected Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
public abstract void makeCar();
}
汽车抽象类里面有一个引擎引用,通过构造方法传递进来。
- (4)、具体汽车类:
一般汽车:
public class NormalCar extends Car {
public NormalCar(Engine engine) {
super(engine);
}
@Override
public void makeCar() {
System.out.println("一般汽车:" + engine.speed());
}
}
SUV汽车:
public class SuvCar extends Car {
public SuvCar(Engine engine) {
super(engine);
}
@Override
public void makeCar() {
System.out.println("SUV汽车:" + engine.speed());
}
}
在具体的汽车类里面,makeCar()方法中,调用不同的引擎。
- (5)、测试类:
public class Client {
public static void main(String[] args) {
//两种引擎
SmallEngine smallEngine = new SmallEngine();
LargeEngine largeEngine = new LargeEngine();
//一般汽车小引擎
NormalCar normalCarSmallEngine = new NormalCar(smallEngine);
normalCarSmallEngine.makeCar();
//一般汽车大引擎
NormalCar normalCarLargeEngine = new NormalCar(largeEngine);
normalCarLargeEngine.makeCar();
//SUV汽车小引擎
SuvCar suvCarSmallEngine = new SuvCar(smallEngine);
suvCarSmallEngine.makeCar();
//SUV汽车大引擎
SuvCar suvCarLargeEngine = new SuvCar(largeEngine);
suvCarLargeEngine.makeCar();
}
}
结果如下:
一般汽车:小马力引擎速度慢
一般汽车:大马力引擎速度快
SUV汽车:小马力引擎速度慢
SUV汽车:大马力引擎速度快
5. 总结
桥接模式在应用开发中不多,一个重要的原因是对于抽象与实现的分离和把。
优点:
- 分离抽象与实现、灵活的扩展以及对客户端来说透明的实现等。
缺点:
- 不容易把握实现,需要一定的经验。