桥接模式
定义:将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化。
桥接模式角色介绍
- Abstraction:抽象角色,内部持有外部传来的Implementor实例,并且定义公共方法。
- RefinedAbstraction:具体角色,扩展Abstraction类。
- Implementor:抽象实现者角色,定义公共方法。
- ConcreteImplementor:具体实现者角色,实现抽象实现者角色。
GOF在提出桥梁模式的时候指出,桥梁模式的用意是”将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化”。这句话有三个关键词,也就是抽象化、实现化和脱耦。
抽象化
存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待。
实现化
抽象化给出的具体实现,就是实现化。
脱耦
所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。
换个话来讲,某些类型由于自身的逻辑,它具有两个或多个维度的变化。这时就要用桥接模式。什么叫维度,就比如形状有圆形和星形,颜色有红色和蓝色。就可以画出红色圆形、蓝色圆形、红色星形、蓝色星形。形状和颜色就是两个维度。桥接模式不止于两个维度,还可以多维度。比如在红色圆形再加上边框。
代码示例
抽象实现者(绘画类)
public interface Drawing {
void drawColor();
void drawBorder();
}
各具体实现者
//颜色维度
public abstract class ColorDrawing implements Drawing{
public void drawBorder() {
//实现边框空方法
}
}
public class DrawRed extends ColorDrawing{
public void drawColor() {
System.out.print("画红色的");
}
}
public class DrawBlue extends ColorDrawing {
public void drawColor() {
System.out.print("画蓝色的");
}
}
//边框维度
public abstract class BorderDrawing implements Drawing{
public void drawColor() {
//实现颜色空方法
}
}
public class DrawDashed extends BorderDrawing{
public void drawBorder() {
System.out.print("虚线边框的");
}
}
public class DrawSolid extends BorderDrawing{
public void drawBorder() {
System.out.print("直线边框的");
}
}
抽象者(形状类)
public abstract class Shape {
protected ColorDrawing colorDrawing;
protected BorderDrawing borderDrawing;
public Shape(ColorDrawing colorDrawing, BorderDrawing borderDrawing) {
this.colorDrawing = colorDrawing;
this.borderDrawing = borderDrawing;
}
public abstract void draw();
}
具体者(圆形、星形)
public class Circle extends Shape {
public Circle(ColorDrawing colorDrawing, BorderDrawing borderDrawing) {
super(colorDrawing, borderDrawing);
}
public void draw() {
colorDrawing.drawColor();
borderDrawing.drawBorder();
System.out.println("圆");
}
}
public class Star extends Shape {
public Star(ColorDrawing colorDrawing, BorderDrawing borderDrawing) {
super(colorDrawing, borderDrawing);
}
public void draw() {
colorDrawing.drawColor();
borderDrawing.drawBorder();
System.out.println("星");
}
}
客户端
ColorDrawing drawRed = new DrawRed();
ColorDrawing drawBlue = new DrawBlue();
BorderDrawing drawSolid = new DrawSolid();
BorderDrawing drawDashed = new DrawDashed();
new Circle(drawRed,drawSolid).draw();//画红色的直线边框的圆
new Circle(drawBlue,drawDashed).draw();//画蓝色的虚线边框的圆
new Star(drawBlue,drawSolid).draw();//画蓝色的直线边框的星
new Star(drawRed,drawDashed).draw();//画红色的虚线边框的星
从上面的例子可以看出,桥接模式解决多维度变化,使抽象和具体解耦。不足之处望指教。