定义
桥接模式(Bridge)将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
桥接模式属于对象结构型模式。
要点
【优点】
抽象与实现分离,扩展能力强。
【缺点】
由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,增加了系统的理解与设计难度。
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 精细抽象化(RefinedAbstraction)角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(ConcreteImplementor)角色:这个角色给出实现化角色接口的具体实现。
场景
咖啡店有多种口味的咖啡,每种口味都有多种规格的杯子型号,请设计代码场景匹配这两个变化维度。
实现
- 抽象类层次
Coffee
/**
* 咖啡(抽象类层次)
*/
public abstract class Coffee {
/**
* 使用聚合关系
*/
protected Cup cup;
protected Coffee(Cup cup) {
this.cup = cup;
}
/**
* 下单咖啡
*/
public abstract void orderCoffee(int count);
}
CoffeeWithMilk
/**
* 咖啡加奶
*/
public class CoffeeWithMilk extends Coffee {
public CoffeeWithMilk(Cup cup) {
super(cup);
}
@Override
public void orderCoffee(int count) {
System.out.println(String.format("加奶咖啡%s x %d", cup.getSize(), count));
}
}
CoffeeWithSugar
/**
* 咖啡加糖
*/
public class CoffeeWithSugar extends Coffee {
public CoffeeWithSugar(Cup cup) {
super(cup);
}
@Override
public void orderCoffee(int count) {
System.out.println(String.format("加糖咖啡%s x %d", cup.getSize(), count));
}
}
- 实现类层次
Cup
/**
* 杯子(实现类层次)
*/
public interface Cup {
String getSize();
}
SmallCup
/**
* 小杯
*/
public class SmallCup implements Cup {
@Override
public String getSize() {
return "小杯";
}
}
MediumCup
/**
* 中杯
*/
public class MediumCup implements Cup {
@Override
public String getSize() {
return "中杯";
}
}
BigCup
/**
* 大杯
*/
public class BigCup implements Cup {
@Override
public String getSize() {
return "大杯";
}
}
Test
public class Test {
public static void main(String[] args) {
Coffee coffee = new CoffeeWithMilk(new MediumCup());
coffee.orderCoffee(3);
Coffee coffee1 = new CoffeeWithSugar(new BigCup());
coffee1.orderCoffee(4);
}
}
输出:
加奶咖啡中杯 x 3
加糖咖啡大杯 x 4
源代码
总结
- 实现了抽象和实现部分的分离,从而极大的提供了系统的灵活性,让抽象部分和实现部分独立开来,这有助于系统进行分层设计,从而产生更好的结构化系统。
- 对于系统的高层部分,只需要知道抽象部分和实现部分的接口就可以了,其它的部分由具体业务来完成。
- 桥接模式替代多层继承方案,可以减少子类的个数,降低系统的管理和维护成本。
- 桥接模式的引入增加了系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。
- 桥接模式要求正确识别出系统中两个独立变化的维度(抽象、和实现),因此其使用范围有一定的局限性,即需要有这样的应用场景。对于那些不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统,桥接模式尤为适用。
在JDBC的源码中用了桥接模式
其他举例场景:
-
银行转账
转账分类: 网上转账,柜台转账,AMT 转账
用户类型:普通用户,银卡用户,金卡用户… -
消息管理
消息分类:即时消息,延时消息
途径类型:手机短信,邮件消息,QQ 消息…