1. 基本概念 桥接模式(Bridge Pattern)是一种结构型设计模式,它的UML图很像一座桥,它通过将【抽象部分】与【实现部分】分离,使它们可以独立变化,从而达到降低系统耦合度的目的。桥接模式的主要目的是通过组合建立两个类之间的联系,而不是继承的方式。
举个简单的例子,图形编辑器中,每一种图形都需要蓝色、红色、黄色不同的颜色,如果不使用桥接模式,可能需要为每一种图形类型和每一种颜色都创建一个具体的子类,而使用桥接模式可以将图形和颜色两个维度分离,两个维度都可以独立进行变化和扩展,如果要新增其他颜色,只需添加新的 Color
子类,不影响图形类;反之亦然。
2. 基本结构 桥接模式的基本结构分为以下几个角色:
抽象Abstraction
:一般是抽象类,定义抽象部分的接口,维护一个对【实现】的引用。
修正抽象RefinedAbstaction
:对抽象接口进行扩展,通常对抽象化的不同维度进行变化或定制。
实现Implementor
: 定义实现部分的接口,提供具体的实现。这个接口通常是抽象化接口的实现。
具体实现ConcreteImplementor
:实现实现化接口的具体类。这些类负责实现实现化接口定义的具体操作。
再举个例子,遥控器就是抽象接口,它具有开关电视的功能,修正抽象就是遥控器的实例,对遥控器的功能进行实现和扩展,而电视就是实现接口,具体品牌的电视机是具体实现,遥控器中包含一个对电视接口的引用,通过这种方式,遥控器和电视的实现被分离,我们可以创建多个遥控器,每个遥控器控制一个品牌的电视机,它们之间独立操作,不受电视品牌的影响,可以独立变化。
3. 简易实现 下面是实现桥接模式的基本步骤:
创建实现接口
1 2 3 interface Implementation { void operationImpl () ; }
创建具体实现类:实际提供服务的对象。
1 2 3 4 5 6 7 8 9 10 11 12 class ConcreteImplementationA implements Implementation { @Override public void operationImpl () { } } class ConcreteImplementationB implements Implementation { @Override public void operationImpl () { } }
创建抽象接口:包含一个对实现化接口的引用。
1 2 3 4 5 6 7 8 9 10 11 12 13 public abstract class Abstraction { protected IImplementor mImplementor; public Abstraction (IImplementor implementor) { this .mImplementor = implementor; } public void operation () { this .mImplementor.operationImpl(); } }
实现抽象接口,创建RefinedAbstaction
类
1 2 3 4 5 6 7 8 9 10 11 12 13 class RefinedAbstraction implements Abstraction { private Implementation implementation; public RefinedAbstraction (Implementation implementation) { this .implementation = implementation; } @Override public void operation () { implementation.operationImpl(); } }
客户端使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Main { public static void main (String[] args) { Implementation implementationA = new ConcreteImplementationA (); Implementation implementationB = new ConcreteImplementationB (); Abstraction abstractionA = new RefinedAbstraction (implementationA); Abstraction abstractionB = new RefinedAbstraction (implementationB); abstractionA.operation(); abstractionB.operation(); } }
4. 万能遥控器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 interface TV { void on () ; void off () ; void tuneChannel () ; } class ATV implements TV { @Override public void on () { System.out.println("A TV is ON" ); } @Override public void off () { System.out.println("A TV is OFF" ); } @Override public void tuneChannel () { System.out.println("Tuning A TV channel" ); } } class BTV implements TV { @Override public void on () { System.out.println("B TV is ON" ); } @Override public void off () { System.out.println("B TV is OFF" ); } @Override public void tuneChannel () { System.out.println("Tuning B TV channel" ); } } abstract class RemoteControl { protected TV tv; public RemoteControl (TV tv) { this .tv = tv; } abstract void turnOn () ; abstract void turnOff () ; abstract void changeChannel () ; } class BasicRemoteControl extends RemoteControl { public BasicRemoteControl (TV tv) { super (tv); } @Override void turnOn () { tv.on(); } @Override void turnOff () { tv.off(); } @Override void changeChannel () { tv.tuneChannel(); } } public class Main { public static void main (String[] args) { TV aTV = new ATV (); TV bTV = new BTV (); RemoteControl basicRemoteForA = new BasicRemoteControl (aTV); RemoteControl basicRemoteForB = new BasicRemoteControl (bTV); basicRemoteForA.turnOn(); basicRemoteForA.changeChannel(); basicRemoteForA.turnOff(); basicRemoteForB.turnOn(); basicRemoteForB.changeChannel(); basicRemoteForB.turnOff(); } }
5. 使用场景 桥接模式在日常开发中使用的并不是特别多,通常在以下情况下使用:
当一个类存在两个独立变化的维度,而且这两个维度都需要进行扩展时,使用桥接模式可以使它们独立变化,减少耦合。
不希望使用继承,或继承导致类爆炸性增长
总体而言,桥接模式适用于那些有多个独立变化维度、需要灵活扩展的系统。