桥接模式

149 阅读5分钟

Bridge

定义

将抽象部分与它的实现部分分离,使它们都可以独立变化


应用场景

1.想要拆分或重组一个具有多重功能的庞杂类(例如能与多个数据库服务器进行交互的类)

类的代码行数越多, 弄清其运作方式就越困难, 对其进行修 改所花费的时间就越长。 一个功能上的变化可能需要在整个 类范围内进行修改, 而且常常会产生错误, 甚至还会有一些 严重的副作用。【桥接模式可以将庞杂类拆分为几个类层次结构。 此后, 你可 以修改任意一个类层次结构而不会影响到其他类层次结构。 这种方法可以简化代码的维护工作, 并将修改已有代码的风 险降到最低。】

2.希望在几个独立维度上扩展一个类

桥接建议将每个维度抽取为独立的类层次。 初始类将相关工作委派给属于对应类层次的对象, 无需自己完成所有工作。

3.如果你需要在运行时切换不同实现方法,可使用桥接模式。

当然并不是说一定要实现这一点, 桥接模式可替换抽象部分中的实现对象,具体操作就和给成员变量赋新值一样简单。


实现方法

1.明确类中独立的维度。 独立的概念可能是: 抽象/平台, 域/ 基础设施, 前端/后端或接口/实现。

2.了解客户端的业务需求, 并在抽象基类中定义它们。

3.确定在所有平台上都可执行的业务。 并在通用实现接口中声明抽象部分所需的业务。

4.为你域内的所有平台创建实现类, 但需确保它们遵循实现部分的接口。

5.在抽象类中添加指向实现类型的引用成员变量。 抽象部分会将大部分工作委派给该成员变量所指向的实现对象。

6.如果你的高层逻辑有多个变体,则可通过扩展抽象基类为每个变体创建一个精确抽象。

7.客户端代码必须将实现对象传递给抽象部分的构造函数才能使其能够相互关联。此后,客户端只需与抽象对象进行交互,无需和实现对象打交道。


优缺点

优点:

1.可以创建与平台无关的类和程序

2.客户端代码仅与高层抽象部分进行互动,不会接触平台的详细信息

3.开闭原则。你可以新增抽象部分和实现部分,且它们之间不会相互影响

4.单一职责原则。抽象部分专注于处理高层逻辑,实现部分处理平台细节

缺点:

对高内聚的类使用该模式可能会让代码更加复杂


结构

UML图

classDiagram
Client --> Abstraction
Abstraction o-->Implementation
Refined Abstraction--|>Abstraction
Concrete Implementations--|>Implementation
class Abstraction{
	-i:Implementation
	+feature1()
	+feature2()
}
class Implementation{
	<<interface>>
	+method1()
	+method2()
	+method3()
}
class Refined Abstraction{
	...
	+featureN()
}

参与者

1.抽象部分( Abstraction ) :提供高层控制逻辑,依赖于完成底层实际工作的实现对象

2.实现部分( Implementation ) :为所有具体实现声明通用接口。抽象部分仅能通过在这里声明的方法与实现对象交互。抽象部分可以列出和实现部分一样的方法,但是抽象部分通常声明一些复杂行为,这些行为依赖于多种由实现部分声明的原语操作

3.具体实现 ( Concrete Implementation ) :包括 特定于平台的代码

4.精确抽象 ( Refined Abstraction ) :提供控制逻辑的变体。与其父类一样,它们通过通用实现接口与不同的实现进行交互

5.客户端( Client ) :仅关心如何与抽象部分合作


通用写法

public interface Implementation {
   void operationImpl();
}
​
public class ConcreteImplementationA implements Implementation{
   @Override
   public void operationImpl() {
       System.out.println("I'm ConcreteImplementationA");
  }
}
​
public class ConcreteImplementationB implements Implementation{
   @Override
   public void operationImpl() {
       System.out.println("I'm ConcreteImplementationB");
  }
}
​
public abstract class Abstraction {
​
   protected Implementation implementation;
​
   public Abstraction(Implementation implementation){
       this.implementation = implementation;
  }
​
   public void operation(){
       this.implementation.operationImpl();
  }
}
​
public class RefinedAbstraction extends Abstraction{
   public RefinedAbstraction(Implementation implementation) {
       super(implementation);
  }
​
   @Override
   public void operation() {
       super.operation();
       System.out.println("refined operation");
  }
}
​
public class Client {
   public static void main(String[] args) {
       Implementation imp = new ConcreteImplementationA();
​
       Abstraction abs = new RefinedAbstraction(imp);
​
       abs.operation();
  }
}

案例

设备和远程控制之间的桥接

该案例将展示远程控制器及其所控制的设备的类之间的分离。

远程控制器是抽象部分,设备则是其实现部分。由于有通用的接口,同一远程控制器可与不同的设备合作,反过来也一样。

桥接模式允许在不改动另一层代码的前提下修改已有类,甚至创建新类

//所有设备通用接口
public interface Device {
   boolean isEnabled();
​
   void enable();
​
   void disable();
​
   int getVolume();
​
   void setVolume(int percent);
​
   int getChannel();
​
   void setChannel(int channel);
​
   void printStatus();
}
​
public class Radio implements Device{
   private boolean on = false;
   private int volume = 30;
   private int channel = 1;
​
   @Override
   public boolean isEnabled() {
       return on;
  }
   @Override
   public void enable() {
       on = true;
  }
​
   @Override
   public void disable() {
       on = false;
  }
​
   @Override
   public int getVolume() {
       return volume;
  }
​
   @Override
   public void setVolume(int volume) {
       if (volume > 100) {
           this.volume = 100;
      } else if (volume < 0) {
           this.volume = 0;
      } else {
           this.volume = volume;
      }
  }
​
   @Override
   public int getChannel() {
       return channel;
  }
​
   @Override
   public void setChannel(int channel) {
       this.channel = channel;
  }
​
   @Override
   public void printStatus() {
       System.out.println("------------------------------------");
       System.out.println("| I'm radio.");
       System.out.println("| I'm " + (on ? "enabled" : "disabled"));
       System.out.println("| Current volume is " + volume + "%");
       System.out.println("| Current channel is " + channel);
       System.out.println("------------------------------------\n");
  }
}
​
public class Tv implements Device {
   private boolean on = false;
   private int volume = 30;
   private int channel = 1;
​
   @Override
   public boolean isEnabled() {
       return on;
  }
​
   @Override
   public void enable() {
       on = true;
  }
​
   @Override
   public void disable() {
       on = false;
  }
​
   @Override
   public int getVolume() {
       return volume;
  }
​
   @Override
   public void setVolume(int volume) {
       if (volume > 100) {
           this.volume = 100;
      } else if (volume < 0) {
           this.volume = 0;
      } else {
           this.volume = volume;
      }
  }
​
   @Override
   public int getChannel() {
       return channel;
  }
​
   @Override
   public void setChannel(int channel) {
       this.channel = channel;
  }
​
   @Override
   public void printStatus() {
       System.out.println("------------------------------------");
       System.out.println("| I'm TV set.");
       System.out.println("| I'm " + (on ? "enabled" : "disabled"));
       System.out.println("| Current volume is " + volume + "%");
       System.out.println("| Current channel is " + channel);
       System.out.println("------------------------------------\n");
  }
}
//所有远程控制器的通用接口
public interface Remote {
   void power();
​
   void volumeDown();
​
   void volumeUp();
​
   void channelDown();
​
   void channelUp();
}
​
//基础远程控制器
public class BasicRemote implements Remote {
   protected Device device;
​
   public BasicRemote() {}
​
   public BasicRemote(Device device) {
       this.device = device;
  }
​
   @Override
   public void power() {
       System.out.println("Remote: power toggle");
       if (device.isEnabled()) {
           device.disable();
      } else {
           device.enable();
      }
  }
​
   @Override
   public void volumeDown() {
       System.out.println("Remote: volume down");
       device.setVolume(device.getVolume() - 10);
  }
​
   @Override
   public void volumeUp() {
       System.out.println("Remote: volume up");
       device.setVolume(device.getVolume() + 10);
  }
​
   @Override
   public void channelDown() {
       System.out.println("Remote: channel down");
       device.setChannel(device.getChannel() - 1);
  }
​
   @Override
   public void channelUp() {
       System.out.println("Remote: channel up");
       device.setChannel(device.getChannel() + 1);
  }
}
​
//高级远程控制器
public class AdvancedRemote extends BasicRemote {
​
   public AdvancedRemote(Device device) {
       super.device = device;
  }
​
   public void mute() {
       System.out.println("Remote: mute");
       device.setVolume(0);
  }
}
public class Client {
   public static void main(String[] args) {
       testDevice(new Tv());
       testDevice(new Radio());
  }
​
   public static void testDevice(Device device) {
       System.out.println("Tests with basic remote.");
       BasicRemote basicRemote = new BasicRemote(device);
       basicRemote.power();
       device.printStatus();
​
       System.out.println("Tests with advanced remote.");
       AdvancedRemote advancedRemote = new AdvancedRemote(device);
       advancedRemote.power();
       advancedRemote.mute();
       device.printStatus();
  }
}