什么是桥接模式?
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
这种模式涉及到一个作为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。
可以解决什么样的问题?
定义说的太抽象了,当我们面对一个由多个维度元素构成的实体时,如果直接通过继承来声明类往往会导致类的数量过多。同过桥接模式可以通过聚合的方式来自由组合对象,灵活,并更容易扩展。
优缺点
优点:
1.抽象和实现的分离。
2.优秀的扩展能力。
3.实现细节对客户透明。
缺点: 桥接模式的引入会增加系统的理解与设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计与编程。
示例
我们来构建一个简单的计算器,能够支持加法和减法两种二则计算。先来定义一个运算的接口 IOperate 以及加法(Add)和减法(Minus)两种算法的实现。
interface IOperate {
int invoke(int a, int b);
}
class Add implements IOperate {
@Override
public int invoke(int a, int b) {
return a + b;
}
}
class Minus implements IOperate {
@Override
public int invoke(int a, int b) {
return a - b;
}
}
接下来定义一个桥接对象 Operation,其中成员变量包括 String 类型的 name,Character 类型的 symbol,以及抽象接口类型的 operate。借由这个对象,我们把自然语义中的“加法”概念和具体加法的行为实现组合了起来。
class Operation {
private String name;
private Character symbol;
private IOperate operate;
public Operation(String name, Character symbol, IOperate operate) {
this.name = name;
this.symbol = symbol;
this.operate = operate;
}
}
现在,我们来构建一个计算器对象,对外暴露一个 cal 方法供客户端调用。
class Calculator {
final Map<Character, Operation> map = Map.of(
'+', new Operation("ADD", '+', new Add()),
'-', new Operation("MINUS", '-', new Minus())
);
public void cal(int a, int b, char operatorSymbol) {
if (!map.containsKey(operatorSymbol)) {
System.out.println("Unknown operation");
return;
}
System.out.println(String.format("%s %c %s = %s", a, operatorSymbol, b, map.get(operatorSymbol).operate.invoke(a, b)));
}
}
最后我们可以进行测试:
public static void main(String[] args) {
final Calculator calculator = new Calculator();
calculator.cal(10, 1, '+');
calculator.cal(10, 2, '-');
calculator.cal(10, 2, '*');
}
Output:
10 + 1 = 11
10 - 2 = 8
Unknown operation
由此可见,我们成功实现了一个简单的计算器功能,这个示例中,算法的自然语义(名称与符号)和算法的实现是隔离开的,互不影响。想象一下,如果我们做的这个计算器其实是一个非常复杂的科学计算器,负责开发计算器基本程序和实现算法的人是两拨不同的团队,借由桥接设计模式,“基本程序”团队可以独立完成计算器的开发,算法的任何更新不会影响到计算器程序的正常执行。