桥接模式
在网上看了很多关于桥接模式的定义,刚开始看的时候,无一不让你感到云里雾里,都是一些过于抽象的解释。
比较通用的定义如下:
桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
初看的时候,你会怎么理解 “抽象化” 和 “实现化”。“抽象” 对应的java 里面的的抽象类,具体类可以继承这个类;“实现” 对应着java 里面的接口,具体类可以实现这个接口。
但是为什么要说:“把抽象化与实现化解耦” 呢?
我的理解是:不进行解耦,都是抽象化,那都要继承基类;都是实现化,就都要实现接口。不管是那一种,都会生成许多类。
我们上面讨论的一个前提场景都是:一个类里面有多个维度都会有扩展的需求。
桥接模式就是适用这种场景下的设计模式:当一个类中有多个维度的变量需要扩展的时候,不管是全用抽象类还是全用实现接口,类都是乘积式的增长。
举个例子:
有图案类,里面有两个属性,颜色和形状。如果颜色(红,黄,绿)有三种,形状(三角形,圆形,正方形)也有三种,我们需要打印图案的颜色和形状,不管是全用抽象类还是全用实现接口,都会产生9个子类,如果再增加一个形状,对应的就要增加3个类。
这是因为,在图案这个类里面,它的两个维度:颜色和形状是相互关联的。你再增加一个颜色的时候,就会增加这个颜色和对应的其他形状的组合。
这个时候,我们如果将颜色和形状两个维度进行 “抽象化和实现化的解耦” 。 将颜色属性单独作为一个接口,有(红,黄,绿)三种具体的实现;同时,将形状属性作为一个抽象,有(三角形,圆形,正方形)三种,但形状里面有的颜色属性。
通过这种方式,将颜色和形状进行解耦,同时,又像有一座桥(bridge)将颜色和形状两个属性进行关联。这也就是桥接模式的得名。
代码示例
一开始的 图案类,具有颜色和形状两个 维度属性。
public interface Pattern {
/**有圆形,正方形,三角形 三种形状*/
public void showShape();
/**有红色,绿色,黄色 三种颜色*/
public void showColor();
}
如果我们要实现3种颜色和3种形状的 实现,就需要9个类,而且每次扩展一个颜色,或者一种形状都是要多增加三个类。
下面来对图案中的颜色和形状属性进行 “抽象化和实现化的解耦”:
颜色:
public interface Color {
void showColor();
}
public class GreenColor implements Color{
@Override
public void showColor() {
System.out.println("这是绿色");
}
}
public class RedColor implements Color{
@Override
public void showColor() {
System.out.println("这是红色");
}
}
public class YellowColor implements Color{
@Override
public void showColor() {
System.out.println("这是黄色");
}
}
形状:
public abstract class Shape {
private Color color;
public Shape(Color color){
this.color = color;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public abstract void showShape();
}
public abstract class SquareShape extends Shape{
public SquareShape(Color color) {
super(color);
}
@Override
public void showShape() {
System.out.println("这是正方形");
}
}
public class TriangleShape extends Shape{
public TriangleShape(Color color) {
super(color);
}
@Override
public void showShape() {
System.out.println("这是三角形");
}
}
public class CircleShape extends Shape{
public CircleShape(Color color) {
super(color);
}
@Override
public void showShape() {
System.out.println("这是圆形");
}
}
客户端:
public class Client {
public static void main(String[] args) {
CircleShape cs = new CircleShape(new GreenColor());
cs.showShape();
cs.getColor().showColor();
TriangleShape ts = new TriangleShape(new GreenColor());
ts.showShape();
ts.getColor().showColor();
}
}
这里也引用一下桥接模式的UML图:
总结一下:桥接模式,就是将一个类里面多个可扩展维度的属性进行 抽象化和实现化的解耦,解耦后又像桥一样将各个属性进行连接。减少了类的实现数量。