一、桥接模式的定义
桥接(Bridge)模式的定义如下:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
- 第一种设计方案是为每一种形状都提供一套各种颜色的版本。
- 第二种设计方案是根据实际需要对形状和颜色进行组合。
采用方案二来进行设计系统中类的个数更少,且系统扩展更为方便。设计方案二即是桥接模式的应用。桥接模式将继承关系转换为关联关系,从而降低了类与类之间的耦合,减少了代码编写量。
二、桥接模式优缺点
桥接(Bridge)模式的优点是:
- 由于抽象与实现分离,所以扩展能力强;
- 其实现细节对客户透明。
缺点是:
由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。
三、桥接模式的实现
可以将抽象化部分与实现化部分分开,取消二者的继承关系,改用组合关系。
桥接(Bridge)模式包含以下主要角色。
- 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
- 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
- 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。
- 具体实现化(Concrete Implementor)角色:给出实现化角色接口的具体实现。
其结构图如图所示:
其实现如下:
public class BridgeTest { public static void main(String[] args) { Implementor imple=new ConcreteImplementorA(); Abstraction abs=new RefinedAbstraction(imple); abs.Operation(); } }
//实现化角色 interface Implementor { public void OperationImpl(); }
//具体实现化角色 class ConcreteImplementorA implements Implementor { public void OperationImpl() { System.out.println("具体实现化(Concrete Implementor)角色被访问" ); } }
//抽象化角色 abstract class Abstraction { protected Implementor imple; protected Abstraction(Implementor imple) { this.imple=imple; } public abstract void Operation(); }
//扩展抽象化角色 class RefinedAbstraction extends Abstraction { protected RefinedAbstraction(Implementor imple) { super(imple); } public void Operation() { System.out.println("扩展抽象化(Refined Abstraction)角色被访问" ); imple.OperationImpl(); } }
四、桥接模式的应用实例
由于桥接模式上面描述比较抽象,此处再举一个关于包的例子进行分析:女士皮包有很多种,可以按用途分、按皮质分、按品牌分、按颜色分、按大小分等,存在多个维度的变化,所以采用桥接模式来实现女士皮包的选购比较合适。
本实例按用途分可选钱包(Wallet)和挎包(HandBag),按颜色分可选黄色(Yellow)和红色(Red)。可以按两个维度定义为颜色类和包类。
颜色类(Color)是一个维度,定义为实现化角色,它有两个具体实现化角色:黄色和红色,通过 getColor() 方法可以选择颜色;包类(Bag)是另一个维度,定义为抽象化角色,它有两个扩展抽象化角色:挎包和钱包,它包含了颜色类对象,通过 getName() 方法可以选择相关颜色的挎包和钱包。
public class BagManage { public static void main(String[] args) { Bag bag = new HandBag(); bag.setColor(new Yellow()); System.out.println(bag.getName()); } } //实现化角色:颜色 interface Color { String getColor(); } //具体实现化角色:黄色 class Yellow implements Color { public String getColor() { return "yellow"; } } //具体实现化角色:红色 class Red implements Color { public String getColor() { return "red"; } } //抽象化角色:包 abstract class Bag { protected Color color; public void setColor(Color color) { this.color=color; } public abstract String getName(); } //扩展抽象化角色:挎包 class HandBag extends Bag { public String getName() { return color.getColor()+"HandBag"; } } //扩展抽象化角色:钱包 class Wallet extends Bag { public String getName() { return color.getColor()+"Wallet"; } }
输出结果为:
yellowHandBag
五、桥接模式的应用场景
桥接模式通常适用于以下场景。
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时。
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。
六、桥接模式模式的扩展
在软件开发中,有时桥接(Bridge)模式可与适配器模式联合使用。当桥接(Bridge)模式的实现化角色的接口与现有类的接口不一致时,可以在二者中间定义一个适配器将二者连接起来,其具体结构图如图所示: