1. 意图(Intent)

将抽象与实现分离开来,使它们可以独立变化。

理解桥梁模式,其实就是理解代码抽象解耦

2. 类图(Class Diagram)

桥梁模式 - 图1

  • Abstraction :定义抽象类的接口
  • Implementor:定义实现类的接口

3. 实现(Implementation)

I 画图案例

我们首先需要一个桥梁,它是一个接口,定义提供的接口方法。 [ Implementor ]

  1. public interface DrawAPI {
  2. public void draw(int radius, int x, int y);
  3. }

然后是一系列实现类:[ ConcreteImplementor ]

  1. public class RedPen implements DrawAPI {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用红色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }
  1. public class GreenPen implements DrawAPI {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用绿色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }
  1. public class BluePen implements DrawAPI {
  2. @Override
  3. public void draw(int radius, int x, int y) {
  4. System.out.println("用蓝色笔画图,radius:" + radius + ", x:" + x + ", y:" + y);
  5. }
  6. }

定义一个抽象类,此类的实现类都需要使用 DrawAPI:[ Abstraction ]

  1. public abstract class Shape {
  2. protected DrawAPI drawAPI;
  3. protected Shape(DrawAPI drawAPI) {
  4. this.drawAPI = drawAPI;
  5. }
  6. public abstract void draw();
  7. }

定义抽象类的子类:

圆形类

  1. public class Circle extends Shape {
  2. private int radius;
  3. public Circle(int radius, DrawAPI drawAPI) {
  4. super(drawAPI);
  5. this.radius = radius;
  6. }
  7. public void draw() {
  8. drawAPI.draw(radius, 0, 0);
  9. }
  10. }

长方形类

  1. public class Rectangle extends Shape {
  2. private int x;
  3. private int y;
  4. public Rectangle(int x, int y, DrawAPI drawAPI) {
  5. super(drawAPI);
  6. this.x = x;
  7. this.y = y;
  8. }
  9. public void draw() {
  10. drawAPI.draw(0, x, y);
  11. }
  12. }

最后,我们来看客户端演示:

  1. public class Client {
  2. public static void main(String[] args) {
  3. Shape greenCircle = new Circle(10, new GreenPen());
  4. Shape redRectangle = new Rectangle(4, 8, new RedPen());
  5. greenCircle.draw();
  6. redRectangle.draw();
  7. }
  8. }

可能大家看上面一步步还不是特别清晰,我把所有的东西整合到一张图上:
bridge-1.png
这回大家应该就知道抽象在哪里,怎么解耦了吧。桥梁模式的优点也是显而易见的,就是非常容易进行扩展。

II 电视遥控

RemoteControl 表示遥控器 [ Abstraction ]、TV 表示电视 [ Implementor ]
桥接模式将遥控器和电视分离开来,从而可以独立改变遥控器或者电视的实现。

我们首先需要一个桥梁,它是一个接口,定义提供的接口方法,本案例中是 TV [ Implementor ]

  1. public abstract class TV {
  2. public abstract void on();
  3. public abstract void off();
  4. public abstract void tuneChannel();
  5. }

然后是一系列实现类:[ ConcreteImplementor ]
索尼电视机类

  1. public class Sony extends TV {
  2. @Override
  3. public void on() {
  4. System.out.println("Sony.on()");
  5. }
  6. @Override
  7. public void off() {
  8. System.out.println("Sony.off()");
  9. }
  10. @Override
  11. public void tuneChannel() {
  12. System.out.println("Sony.tuneChannel()");
  13. }
  14. }

RCA 电视机类

  1. public class RCA extends TV {
  2. @Override
  3. public void on() {
  4. System.out.println("RCA.on()");
  5. }
  6. @Override
  7. public void off() {
  8. System.out.println("RCA.off()");
  9. }
  10. @Override
  11. public void tuneChannel() {
  12. System.out.println("RCA.tuneChannel()");
  13. }
  14. }

定义一个抽象类,此类的实现类都需要使用 TV ,本案例中是遥控器抽象类:[ Abstraction ]

  1. public abstract class RemoteControl {
  2. protected TV tv;
  3. public RemoteControl(TV tv) {
  4. this.tv = tv;
  5. }
  6. public abstract void on();
  7. public abstract void off();
  8. public abstract void tuneChannel();
  9. }

定义遥控器抽象类的子类:

A 遥控器

  1. public class ConcreteRemoteControlA extends RemoteControl {
  2. public ConcreteRemoteControl1(TV tv) {
  3. super(tv);
  4. }
  5. @Override
  6. public void on() {
  7. System.out.println("ConcreteRemoteControlA.on()");
  8. tv.on();
  9. }
  10. @Override
  11. public void off() {
  12. System.out.println("ConcreteRemoteControlA.off()");
  13. tv.off();
  14. }
  15. @Override
  16. public void tuneChannel() {
  17. System.out.println("ConcreteRemoteControlA.tuneChannel()");
  18. tv.tuneChannel();
  19. }
  20. }

B 遥控器

  1. public class ConcreteRemoteControlB extends RemoteControl {
  2. public ConcreteRemoteControl1(TV tv) {
  3. super(tv);
  4. }
  5. @Override
  6. public void on() {
  7. System.out.println("ConcreteRemoteControlB.on()");
  8. tv.on();
  9. }
  10. @Override
  11. public void off() {
  12. System.out.println("ConcreteRemoteControlB.off()");
  13. tv.off();
  14. }
  15. @Override
  16. public void tuneChannel() {
  17. System.out.println("ConcreteRemoteControlB.tuneChannel()");
  18. tv.tuneChannel();
  19. }
  20. }

客户端使用代码

  1. public class Client {
  2. public static void main(String[] args) {
  3. RemoteControl remoteControl1 = new ConcreteRemoteControl1(new RCA());
  4. remoteControl1.on();
  5. remoteControl1.off();
  6. remoteControl1.tuneChannel();
  7. RemoteControl remoteControl2 = new ConcreteRemoteControl2(new Sony());
  8. remoteControl2.on();
  9. remoteControl2.off();
  10. remoteControl2.tuneChannel();
  11. }
  12. }

4. JDK

  • AWT (It provides an abstraction layer which maps onto the native OS the windowing support.)
  • JDBC