title: 设计模式之桥接模式
date: 2015-01-16 10:32:00
categories:
- 设计
- 设计模式
tags:
- 设计
- 设计模式
permalink: /pages/b05f5f/
桥接模式 (Bridge) 是一种结构型设计模式, 可将抽象部分与实现部分分离,使它们都可以独立的变化。
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。抽象化角色和具体化角色都应该可以被子类扩展。在这种情况下,桥接模式可以灵活地组合不同的抽象化角色和具体化角色,并独立化地扩展。
设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
【Implementor】定义实现接口。
interface Implementor {
// 实现抽象部分需要的某些具体功能
public void operationImpl();
}
【Abstraction】定义抽象接口。
abstract class Abstraction {
// 持有一个 Implementor 对象,形成聚合关系
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
// 可能需要转调实现部分的具体实现
public void operation() {
implementor.operationImpl();
}
}
【ConcreteImplementor】实现 Implementor 中定义的接口。
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
// 真正的实现
System.out.println("具体实现A");
}
}
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
// 真正的实现
System.out.println("具体实现B");
}
}
【RefinedAbstraction】扩展 Abstraction 类。
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
public void otherOperation() {
// 实现一定的功能,可能会使用具体实现部分的实现方法,
// 但是本方法更大的可能是使用 Abstraction 中定义的方法,
// 通过组合使用 Abstraction 中定义的方法来完成更多的功能。
}
}
【客户端】
public class BridgePattern {
public static void main(String[] args) {
Implementor implementor = new ConcreteImplementorA();
RefinedAbstraction abstraction = new RefinedAbstraction(implementor);
abstraction.operation();
abstraction.otherOperation();
}
}
【输出】
具体实现A
其他操作
遥控器基类声明了一个指向设备对象的引用成员变量。 所有遥控器通过通用设备接口与设备进行交互, 使得同一个遥控器可以支持不同类型的设备。
你可以开发独立于设备类的遥控器类, 只需新建一个遥控器子类即可。 例如, 基础遥控器可能只有两个按钮, 但你可在其基础上扩展新功能, 比如额外的一节电池或一块触摸屏。
客户端代码通过遥控器构造函数将特定种类的遥控器与设备对象连接起来。
// “抽象部分”定义了两个类层次结构中“控制”部分的接口。它管理着一个指向“实
// 现部分”层次结构中对象的引用,并会将所有真实工作委派给该对象。
class RemoteControl is
protected field device: Device
constructor RemoteControl(device: Device) is
this.device = device
method togglePower() is
if (device.isEnabled()) then
device.disable()
else
device.enable()
method volumeDown() is
device.setVolume(device.getVolume() - 10)
method volumeUp() is
device.setVolume(device.getVolume() + 10)
method channelDown() is
device.setChannel(device.getChannel() - 1)
method channelUp() is
device.setChannel(device.getChannel() + 1)
// 你可以独立于设备类的方式从抽象层中扩展类。
class AdvancedRemoteControl extends RemoteControl is
method mute() is
device.setVolume(0)
// “实现部分”接口声明了在所有具体实现类中通用的方法。它不需要与抽象接口相
// 匹配。实际上,这两个接口可以完全不一样。通常实现接口只提供原语操作,而
// 抽象接口则会基于这些操作定义较高层次的操作。
interface Device is
method isEnabled()
method enable()
method disable()
method getVolume()
method setVolume(percent)
method getChannel()
method setChannel(channel)
// 所有设备都遵循相同的接口。
class Tv implements Device is
// ...
class Radio implements Device is
// ...
// 客户端代码中的某个位置。
tv = new Tv()
remote = new RemoteControl(tv)
remote.togglePower()
radio = new Radio()
remote = new AdvancedRemoteControl(radio)
使用示例: 桥接模式在处理跨平台应用、 支持多种类型的数据库服务器或与多个特定种类 (例如云平台和社交网络等) 的 API 供应商协作时会特别有用。
识别方法: 桥接可以通过一些控制实体及其所依赖的多个不同平台之间的明确区别来进行识别。
Java 中桥接模式应用最经典的代表无疑是日志组件 slf4j 的桥接 jar 包。
假如,你正在开发应用程序所调用的组件当中已经使用了 common-logging,这时你需要 jcl-over-slf4j.jar 把日志信息输出重定向到 slf4j-api,slf4j-api 再去调用 slf4j 实际依赖的日志组件。这个过程称为桥接。下图是官方的 slf4j 桥接策略图:
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。