0x01:桥接模式简介
桥接模式是将抽象部分与它的实现部分分离,使它们都可以独立地变化,而不会直接影响到其他部分。是一种对象结构型模式,又称接口(interface)模式。UML类图如下:
主要角色如下:
Implementor:实现化角色,它是接口或者抽象类,定义角色必需的行为和属性;这个接口不一定要与Abstraction的接口完全一致,事实上这两个接口可以完全不同,一般而言,Implementor接口仅提供基本操作,而Abstraction定义的接口可能会做更多更复杂的操作。Implementor接口对这些基本操作进行了声明,而具体实现交给其子类。通过关联关系,Abstraction不仅拥有自己的方法,还可以调用Implementor中定义的方法,使用关联关系来替代继承关系;
ConcreteImplementor:具体实现化角色,实现接口或抽象类定义的方法或属性。在不同的ConcreteImplementor中提供基本操作的不同实现,在程序运行时,ConcreteImplementor对象将替换其父类对象,提供给抽象类具体的业务操作方法;
Abstraction:抽象化角色,定义出该角色的行为,同时保存一个对实现化角色的引用;它一般是抽象类而不是接口,其中定义了一个Implementor(实现类接口)类型的对象并可以维护该对象,它与Implementor之间具有关联关系,它既可以包含抽象业务方法,也可以包含具体业务方法;
RefinedAbstraction:扩充抽象类角色,引用实现化角色对抽象化角色进行扩充。通常情况下,它不再是抽象类而是具体类,它实现了在Abstraction中声明的抽象业务方法,在RefinedAbstraction中可以调用在Implementor中定义的业务方法;
0x02:桥接模式典型实现
Implementor抽象类
public abstract class Implementor { public abstract void operatorA(); public abstract void operatorB(); }
ConcreteImplementor:这里可以编写多个具体实现类
public class ConcreteImplementorA extends Implementor { @Override public void operatorA() { System.out.println("具体实现ConcreteImplementorA的operatorA执行"); } @Override public void operatorB() { System.out.println("具体实现ConcreteImplementorA的operatorB执行"); } } public class ConcreteImplementorB extends Implementor { @Override public void operatorA() { System.out.println("具体实现ConcreteImplementorB的operatorA执行"); } @Override public void operatorB() { System.out.println("具体实现ConcreteImplementorB的operatorB执行"); } }
Abstraction抽象类
public abstract class Abstraction { private Implementor implementor; //约束子类必须实现该构造函数 public Abstraction(Implementor implementor) { this.implementor = implementor; } public Implementor getImplementor() { return implementor; } //自身的行为和属性 public void request() { //TODO 可以添加操作 } }
RefinedAbstraction
public class RefinedAbstraction extends Abstraction { //覆写构造函数 public RefinedAbstraction(Implementor implementor) { super(implementor); } //修正父类行为 @Override public void request() { super.request(); super.getImplementor().operatorA(); } }
桥接模式测试代码
public class Client { public static void main(String[] args) { Implementor implementor1 = new ConcreteImplementorA(); Abstraction abstraction1 = new RefinedAbstraction(Implementor1); abstraction1.request(); Implementor implementor2 = new ConcreteImplementorB(); Abstraction abstraction2 = new RefinedAbstraction(Implementor2); abstraction2.request(); } }
0x03:桥接模式的应用场景
因为桥接模式又称接口模式,所以可以理解为提供一个标准接口,然后多种实现。这种场景在项目开发中,在普遍不过了。
- 预警系统的信息处理方式
一般预警系统都提供了消息通知的功能,而消息通知的渠道多种多样,主要有站内消息、邮件消息和短信消息。
- 多厂商对接
在做项目时,经常遇到一个同样的功能对接多个厂商的情况。这种情况普遍存在设备对接的项目中,之前小编在做柜面系统时,经常遇到刷卡器、身份证读取器等设备同时对接多个厂商的情况。
- 日志框架
java领域的日志框架,接口定义与具体实现框架。常常也是基于桥接模式实现适配使用的。
桥接模式的使用场景
- 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展;
- 不希望使用继承或因为多层次继承导致系统类的个数急剧增加的系统 ;
- 如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系;