前言
桥接模式通过分离一个抽象接口和它的实现部分,使得设计可以按两个维度独立扩展
桥接模式(Bridge): 将抽象化与实现化解耦,使得二者可以独立变化。是为了避免直接继承带来的子类爆炸
像我们常用的JDBC桥DriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了
实现
示例一
汽车由引擎与品牌组成,但引擎与品牌独立变化,在两个变化维度中任意扩展一个,都不需要修改原有系统
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
public interface Engine {
void start();
}
public class HybridEngine implements Engine{ @Override public void start() { System.out.println("混合发动机启动......"); } }
public abstract class Car {
private Engine engine;
public Car(Engine engine) { this.engine = engine; }
public abstract void drive();
public Engine getEngine() { return engine; } }
public abstract class BrandCar extends Car {
public BrandCar(Engine engine) { super(engine); }
@Override public void drive() { getEngine().start(); System.out.println("正在驾驶: " + brand() + "汽车"); }
public abstract String brand(); }
public class BenBrandCar extends BrandCar { public BenBrandCar(Engine engine) { super(engine); }
@Override public String brand() { return "奔驰"; } }
public class BridgeTest {
public static void main(String[] args) { BrandCar brandCar = new BenBrandCar(new HybridEngine()); brandCar.drive(); }
}
|
使用桥接模式的好处在于,如果要增加一种引擎,只需要针对Engine派生一个新的子类,如果要增加一个品牌车,只需要针对BrandCar派生一个子类,任何BrandCar的子类都可以和任何一种Engine自由组合,即一辆汽车的两个维度:品牌和引擎都可以独立地变化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ┌───────────┐ │ Car │ └───────────┘ ▲ │ ┌───────────┐ ┌─────────┐ │BrandCar │ ─ ─ ─>│ Engine │ └───────────┘ └─────────┘ ▲ ▲ ┌────────┼────────┐ │ ┌──────────────┐ │ │ ├─│ FuelEngine │ ┌────────────┐ ┌───────────┐ │ └──────────────┘ │AudiBrandCar│ │BenBrandCar│ │ ┌──────────────┐ └────────────┘ └───────────┘ ├─│ElectricEngine│ │ └──────────────┘ │ ┌──────────────┐ └─│ HybridEngine │ └──────────────┘
|
不要过度使用继承,而是优先拆分某些部件,使用组合的方式来扩展功能
示例二
画笔,可以画正方形、长方形、圆形……又可以对这些不同形状上不同颜色
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
|
public interface Color {
void paint(String shape);
}
public class WhiteColor implements Color{ @Override public void paint(String shape) { System.out.println("使用白色画: " + shape); } }
public class BlueColor implements Color { @Override public void paint(String shape) { System.out.println("使用蓝色画: " + shape); } }
public abstract class Shape {
private Color color;
public void setColor(Color color) { this.color = color; }
public abstract void draw();
public Color getColor() { return color; } }
public class CircleShape extends Shape { @Override public void draw() { getColor().paint("圆形"); } }
public class SquareShape extends Shape{ @Override public void draw() { getColor().paint("正方形"); } }
public class PaintBridgeTest {
public static void main(String[] args) { Color white = new WhiteColor();
Shape circle = new CircleShape();
circle.setColor(white); circle.draw();
Color blue = new BlueColor();
circle.setColor(blue); circle.draw();
Shape square = new SquareShape();
square.setColor(blue); square.draw();
square.setColor(white); square.draw(); }
}
|
以上形状类Shape就像一个桥接,可以组合任一形状和颜色进行绘画,同时可以分别拓展形状(继承Shape类)和颜色(实现Color接口)