Java设计模式之桥梁(Bridge)模式
作者:通信侠
桥梁模式的结构
桥梁模式是对象的结构模式。
如上图所示,系统含有两个等级结构:
- 由抽象化角色和修正抽象化角色组成的抽象化等级结构。
- 由实现化角色和两个具体实现化角色所组成的实现化等级结构。
桥梁模式所涉及的角色有:
- 抽象化(Abstraction)角色:抽象化给出的定义,并保存一个对实现化对象的引用。
- 修正抽象(Refined Abstraction)化角色:扩展抽象化角色,改变和修正父类对抽象化的定义。
- 实现化(Implementor)角色:这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。 实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化(Concrete Implementor)角色:这个角色给出实现化角色接口的具体实现。
对象是对行为的封装,而行为是由方法实现的。在这个示意性系统里,抽象化等级结构中的类封装了operation()方法;而实现化等级结构中的类封装的是operationImp()方法。
抽象化等级结构中的商业方法通过向对应的实现化对象的委派实现自己的功能,这意味着抽象化角色可以通过向不同的实例化对象委派,来达到动态地转换自己的功能的目的。
示意性源码:
抽象化角色,商业方法operation()的实现是通过向实现化对象的委派(调用operationImp()方法)实现的。
abstract public class Abstraction { protected Implementor imp; /** * 某个商业方法 */ public void operation() { imp.operationImp(); } }
修正抽象化角色,商业方法被置换掉了。
public class RefinedAbstraction extends Abstraction { /** * 某个商业方法在修正抽象化角色的实现 */ public void operation() { // improved logic } }
实现化角色抽象类Implementor中声明一个抽象方法operationImp(),这个方法必须由具体子类实现。
abstract public class Implementor { /** * 某个商业方法的实现化声明 */ public abstract void operationImp(); }
具体实现化角色实现了抽象类Implementor所声明的商业方法operationImp()。
public class ConcreteImplementorA extends Implementor { /** * 某个商业方法的实现化实现 */ public void operationImp() { System.out.println("Do something..."); } }
一般而言,实现化角色中的每一个方法都应当有一个抽象化角色中的某一个方法与之相对应,但是,反过来则不一定。换言之,抽象化角色的接口比实现化角色的接口宽。抽象化角色除了提供与实现化角色相关的方法之外,还有可能提供其他的商业方法;而实现化角色则往往仅为实现抽象化角色的相关行为而存在。
例子
空中巴士(Airbus)、波音(Boeing)和麦道(McDonnell-Douglas)都是飞机制造商,它们都生产载客飞机(Passenger Plane)和载货飞机(Cargo Plane)。现在需要设计一个系统,描述这些飞机制造商以及它们所制造的飞机种类。
设计方案一
在这个设计方案里,有两个子接口:客机和货机。所有的具体飞机又都要继承自Airbus,Boeing和MD等超类。这样一来,每一个具体飞机都带有两个超类型:飞机制造商类型,客、货机类型。
这样设计造成具体飞机与飞机制造商、飞机种类之间的耦合过强,无法满足“开-闭原则”:
- 需要向系统引进新的飞机制造商;
- 需要向系统引进新的飞机类型。
设计方案二
桥梁模式,抽象化角色——飞机的种类,实现化角色——飞机制造商。
客机和货机经过一个飞机的“转世”桥梁,可以分别“投胎”到空中巴士、波音和麦道等飞机制造商哪里,“出生”为不同牌子的飞机。
由于这个“转世”桥梁实际上是一个聚合关系,因此可以动态地变化。所以如果系统需要加入新的飞机种类或者飞机制造商的话,已有的各个角色不必改变,需要改变的仅仅是一个多态性的聚合关系。
示意性源代码:
抽象化角色类Airplane。
abstract public class Airplane { protected AirplaneMaker airplaneMaker; abstract public void fly(); protected Airplane(AirplaneMaker airplaneMaker) { this.airplaneMaker = airplaneMaker; } }
载客飞机和载货飞机属于修正抽象化角色。
public class PassengerPlane extends Airplane { public void fly() { // Write your code here airplaneMaker.produce(); } public PassengerPlane(AirplaneMaker airplaneMaker) { super(airplaneMaker); } } public class CargoPlane extends Airplane { public void fly() { // Write your code here airplaneMaker.produce(); } public CargoPlane(AirplaneMaker airplaneMaker) { super(airplaneMaker); } }
实现化角色是飞机制造商AirplaneMaker,给出修正抽象化角色所需要实现的接口。
abstract public class AirplaneMaker { abstract public void produce(); }
具体实现化角色是Airbus、Boeing、MD。
public class Airbus extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by Airbus"); } } public class Boeing extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by Boeing"); } } public class MD extends AirplaneMaker { public void produce() { // Write your code here System.out.println("produce by MD"); } }
客户端代码。
public class BridgePatternDemo { public static void main(String[] args) { Airplane mdPassengerPlane = new PassengerPlane(new MD()); Airplane mdCargoPlane = new CargoPlane(new MD()); mdPassengerPlane.fly(); mdCargoPlane.fly(); Airplane boeingPassengerPlane = new PassengerPlane(new Boeing()); Airplane boeingCargoPlane = new CargoPlane(new Boeing()); boeingPassengerPlane.fly(); boeingCargoPlane.fly(); } }
现在,如果需要增加新的飞机制造商或者新的飞机种类,只需要向系统引进一个新的修正抽象化角色或者一个新的具体实现化角色即可。即系统的功能可以在不修改已有代码的情况下得到扩展,符合“开-闭”原则。
到此这篇关于Java设计模式之桥梁(Bridge)模式的文章就介绍到这了,更多相关Java 桥梁模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!