模式动机
桥接模式(Bridge Pattern)是一种很实用的结构型模式,如果系统中某个类存在两个独立变化的维度,通过该模式可以将这两个维度分离出来,使得两者可以独立扩展。桥接模式用一种巧妙的方式处理多层继承存在的问题,用抽象关联取代了传统的多重继承,将类之间的静态继承关系转换为动态的对象组合关系,使得系统更加灵活,并易于扩展,同时有效地控制了系统中类的个数。
模式定义
- 对象结构型模式,又称为柄体(Handle and Body)模式或接口(Interface)模式
- 用抽象关联取代了传统的多层继承
- 将类之间的静态继承关系转换为动态的对象组合关系
模式结构
案例实现
案例背景
案例结构
代码实现
public abstract class Pen {
protected Color color;
public void setColor(Color color) {
this.color = color;
}
public abstract void draw(String name);
}
public class BigPen extends Pen {
@Override
public void draw(String name) {
String penType = "大号毛笔绘制";
this.color.bepaint(penType,name);
}
}
public class MiddlePen extends Pen {
@Override
public void draw(String name) {
String penType = "中号毛笔绘制";
this.color.bepaint(penType,name);
}
}
public class SmallPen extends Pen {
@Override
public void draw(String name) {
String penType = "小号毛笔绘制";
this.color.bepaint(penType,name);
}
}
public interface Color {
//用于图形着色的方法
void bepaint(String penType,String name);
}
public class Red implements Color {
@Override
public void bepaint(String penType, String name) {
System.out.println(penType+"红色的"+name+".");
}
}
public class White implements Color {
@Override
public void bepaint(String penType, String name) {
System.out.println(penType+"白色的"+name+".");
}
}
public class Green implements Color {
@Override
public void bepaint(String penType, String name) {
System.out.println(penType+"绿色的"+name+".");
}
}
public class Blue implements Color {
@Override
public void bepaint(String penType, String name) {
System.out.println(penType+"蓝色的"+name+".");
}
}
public class Black implements Color {
@Override
public void bepaint(String penType, String name) {
System.out.println(penType+"黑色的"+name+".");
}
}
public class Client {
public static void main(String[] args) {
Color color;
Pen pen;
color = (Color) XMLUtilPen.getBean("color");
pen = (Pen) XMLUtilPen.getBean("pen");
pen.setColor(color);
pen.draw("鲜花");
}
}
模式分析
- 桥接模式中体现了很多OOP的思想,包括开闭原则、合成复用原则、里氏代换原则、依赖倒转原则等。
- 桥接模式可以从接口中分离实现功能,设计更具有扩展性。
- 桥接模式减少了子类个数,代码简洁。
- 重点理解如何将抽象化(Abstraction)和实现化(Implementation)脱耦,使得两者可以独立变化。
- 脱耦
- 将抽象化和实现化之间的耦合解开,或者说是将强关联改换成弱关联,将两个角色之间的继承关系改为关联关系。
- 桥接模式中的所谓脱耦就是指在一个软件系统的抽象化和实现化之间使用关联关系(组合或者聚合)而不是继承关系,从而使得两者可以相对独立地变化。
- 继承是强耦合关系。
总结
模式优点
- 分离抽象接口及其实现部分
- 可以取代多层继承方案,极大地减少了子类的个数
- 提高了系统的可扩展性,在两个变化维度中任意扩展一个维度,不需要修改原有系统,符合开闭原则
模式缺点
- 会增加系统的理解与设计难度,由于关联关系建立在抽象层,要求开发者一开始就要针对抽象层进行设计与编程
- 正确识别出系统中两个独立变化的维度并不是一件容易的事情
应用情形
- 需要在抽象化和具体化之间增加更多的灵活性,避免在两个层次之间建立静态的继承关系
- 抽象部分和实现部分可以以继承的方式独立扩展而互不影响
- 一个类存在两个(或多个)独立变化的维度,且这两个(或多个)维度都需要独立地进行扩展
- 不希望使用继承或因为多层继承导致系统类的个数急剧增加的系统
模式扩展
桥接模式与适配器模式经常联合使用,适配器模式可以解决两个已有接口间不兼容的问题,适配器采用增加适配器的方式将第三方类集成到系统中;而桥接模式则通过接口继承或者类继承的方式对系统进行扩展。两个模式用于设计的不同阶段,通常情况下桥接模式用于系统的初步设计,对于存在两个独立变化维度的类可以将其分为抽象化和实现化两个角色,使它们可以分别进行变化。初步设计完成后,当发现系统与已有类无法协同工作时,可以采用适配器模式。