桥接模式,也叫桥梁模式(Bridge Pattern),是接口型模式的一种。
定义
将抽象(Abstraction)和实现(Implementation)解耦,使得两者可以独立地变化。
结构图
从蜡笔到毛笔的例子,解决方案是提供两个父类,它们都包含相应的子类,实现了笔和颜色两个维度自由变化,笔和颜色自由组合。
优点
- 代码数量减少。桥接模式将继承关系转换为组合关系,从而降低了系统间的耦合,减少了系统中类的数量,也减少了代码编写量。
- 可扩展性变好。脱耦实现了系统的多个角度分类,每个角度都可以独立地变化扩充。有新的需求不管抽象还是实现直接继承即可,具体可以看下面的测试代码。
- 降低耦合性。
缺点
- 桥接模式的引入会增加系统的理解和设计难度,由于聚合关联关系建立在抽象层,要求开发者针对抽象进行设计和编程。
- 桥接模式要求正确地识别出系统中两个独立变化的维度,所以使用范围有一定的局限性。
桥接器和适配器比较
共同:两者都是让两种东西配合工作。
不同:(1)适配器是改变两个接口,让他们相容。桥接模式的目的是分离和实现,两者接口可以不同,是为了解耦。
(2)适配器是先有两边的东西,再有适配器。桥接模式是先有两边的东西,桥好了之后,两边的东西还可以变化。
适用情况
- 系统需要在构件抽象化和具体化之间增加更多的灵活性。
- 角色的任何改变不影响客户端(实现化角色的改变对客户端完全是透明的)。
- 系统需要抽象化角色和实现化角色之间进行动态耦合。
JDK提供的JDBC数据库访问接口API正是经典的桥接模式的实现者,接口内部可以通过实现接口来扩展针对不同数据库的具体实现来进行扩展,而对外的仅仅只是一个统一的接口调用。
JRE也是一个很好地桥。它的跨平台性,只要是java在linux和windows上都可运行。
测试代码
/**
* 客户端
*/
public class BridgeClient {
public static void main(String[] args) {
Abstraction a = new AbstractionA("A");
a.setImplementor(new ConcreteImplemtorA());
a.operation();
a.setImplementor(new ConcreteImplemtorB());
a.operation();
Abstraction b = new AbstractionB("B");
b.setImplementor(new ConcreteImplemtorA());
b.operation();
b.setImplementor(new ConcreteImplemtorB());
b.operation();
// 这样通过使用“组合/聚合复用原则”
// 如果继续有AbstractionC ... 或者ConcreteImplemtorC ...
// 只需要扩展类即可,不需要修改现有类,符合“开放-封闭”原则
}
}
-------------------------------------------------------------------------
//抽象化部分
public abstract class Abstraction {
protected Implementor implementor;// 桥接模式的关键,使得Abstraction聚合Implementor
private String name;
public Abstraction(String name) {
this.setName(name);
}
public void setImplementor(Implementor implementor) {
this.implementor = implementor;
}
public void operation() {
System.out.print("Abstraction-" + this.getName() + ": ");
implementor.operation();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class AbstractionA extends Abstraction {
public AbstractionA(String name) {
super(name);
}
@Override
public void operation() {
super.operation();
}
}
class AbstractionB extends Abstraction {
public AbstractionB(String name) {
super(name);
}
@Override
public void operation() {
super.operation();
}
}
------------------------------------------------------------------
//实现化部分
public abstract class Implementor {
public abstract void operation();
}
class ConcreteImplemtorA extends Implementor {
@Override
public void operation() {
System.out.println("ConcreteImplemtorA的方法执行");
}
}
class ConcreteImplemtorB extends Implementor {
@Override
public void operation() {
System.out.println("ConcreteImplemtorB的方法执行");
}
}