桥接是一种结构型设计模式, 可将业务逻辑或一个大类拆分为不同的层次结构, 从而能独立地进行开发。
层次结构中的第一层 (通常称为抽象部分) 将包含对第二层 (实现部分) 对象的引用。 抽象部分将能将一些 (有时是绝大部分) 对自己的调用委派给实现部分的对象。 所有的实现部分都有一个通用接口, 因此它们能在抽象部分内部相互替换。
使用示例:桥接模式在处理跨平台应用、 支持多种类型的数据库服务器或与多个特定种类 (例如云平台和社交网络等) 的 API 供应商协作时会特别有用。
识别方法:桥接可以通过一些控制实体及其所依赖的多个不同平台之间的明确区别来进行识别。
01设备和远程控制之间的桥接
本例展示了远程控制器及其所控制的设备的类之间的分离。
远程控制器是抽象部分, 设备则是其实现部分。 由于有通用的接口, 同一远程控制器可与不同的设备合作, 反过来也一样。
桥接模式允许在不改动另一层次代码的前提下修改已有类, 甚至创建新类。
02devices
devices/Device.java: 所有设备的通用接口
package refactoring_guru.bridge.example.devices;public interface Device { boolean isEnabled(); void enable(); void disable(); int getVolume(); void setVolume(int percent); int getChannel(); void setChannel(int channel); void printStatus(); }
devices/Radio.java: 收音机
package refactoring_guru.bridge.example.devices;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"); } }
devices/Tv.java: 电视机
package refactoring_guru.bridge.example.devices;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"); } }
remotes/Remote.java: 所有远程控制器的通用接口
package refactoring_guru.bridge.example.remotes;public interface Remote { void power(); void volumeDown(); void volumeUp(); void channelDown(); void channelUp();}
remotes/BasicRemote.java: 基础远程控制器
package refactoring_guru.bridge.example.remotes;import refactoring_guru.bridge.example.devices.Device;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); } }
remotes/AdvancedRemote.java: 高级远程控制器
package refactoring_guru.bridge.example.remotes;import refactoring_guru.bridge.example.devices.Device;public class AdvancedRemote extends BasicRemote { public AdvancedRemote(Device device) { super.device = device; } public void mute() { System.out.println("Remote: mute"); device.setVolume(0); } }
Demo.java: 客户端代码
package refactoring_guru.bridge.example;import refactoring_guru.bridge.example.devices.Device;import refactoring_guru.bridge.example.devices.Radio;import refactoring_guru.bridge.example.devices.Tv;import refactoring_guru.bridge.example.remotes.AdvancedRemote;import refactoring_guru.bridge.example.remotes.BasicRemote;public class Demo { 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(); } }
OutputDemo.txt: 执行结果
Tests with basic remote. Remote: power toggle | I'm TV set. | I'm enabled | Current volume is 30% | Current channel is 1 Tests with advanced remote. Remote: power toggle Remote: mute | I'm TV set. | I'm disabled | Current volume is 0% | Current channel is 1 Tests with basic remote. Remote: power toggle | I'm radio. | I'm enabled | Current volume is 30% | Current channel is 1 Tests with advanced remote. Remote: power toggle Remote: mute | I'm radio. | I'm disabled | Current volume is 0% | Current channel is 1
以上是23种设计模式漫画版系列—桥接模式,全部内容了。