BRIGE(桥接) ------ 对象结构型模式

[size=large]1、意图
将抽象部分与它的实现部分分离,使它们都可以独立地变化,通常被认为是双重抽象。
2、别名
Handle/Body
3、动机
当一个抽象类可能有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但是此方法有时不够灵活。继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分和实现部分进行独立地进行修改、扩充和重用。
让我们考虑在一个用户界面工具箱中,一个可移植的Window抽象部分的实现。例如,这一抽象部分应该允许用户开发一些在X Window System和IBM的presentation Manager(PM)系统中都可以用到的应用程序。运用继承机制,我们可以定义Window抽象类和它的两个子类XWindow与PMWindow,由它们分别实现不同系统平台上的Window界面。但是继承机制有两个不足之处:
1)扩展Window抽象使之适用于不同种类的窗口或新的系统平台很不方便。假设有Window的一个子类Icon Window,它专门将Window抽象用于图标处理。为了使Icon Window支持两个系统平台,我们必须实现两个新类XIconWindow和PMIconWindow,更为糟糕的是,我们不得不为每一种类型的窗口都定义两个类。而为了支持第三个系统平台我们还必须为每一种窗口定义一个新的Window子类
2)继承机制使得客户代码与平台相关。每当客户创建一个窗口时,必须要实例化一个具体的类,这个类有特定的实现部分。例如,创建Xwindow对象会将Window抽象与Xwindow的实现部分绑定起来,这使得客户程序依赖于X Window的实现部分。这将使得很难讲客户代码移植到其他平台上去。
客户在创建窗口时应该不涉及到其具体实现部分。仅仅是窗口的实现部分依赖于运行的平台。这样客户代码在创建窗口时就不应涉及到特定的平台。
Bridge模式解决以上问题的方法是,将Window抽象和它的实现部分分别放在独立的类层次结构中。其中一个类层次结构针对窗口接口(Window、IconWindow、TransientWindow),另外一个独立的类层次结构针对平台相关的窗口实现部分,这个类层次结构的根类为WindowImpl。例如XwindowImpl之类提供了一个X Window系统的实现。
[color=red]对Window之类的所有操作都是用WindowImpl接口中的抽象操作实现的[/color]。这就将窗口的抽象与系统平台相关的实现部分分离开来。因此,我么将Window与WindowImpl之间的关系城之为桥接,因为它在抽象类与它的实现之间起到了桥梁作用,使它们可以独立地变化。

4、适用性
以下一些情况下使用Bridge模式:
你不希望在抽象和它的实现之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。
类的抽象以及它的实现都应该可以通过生成子类的方式加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象部分的修改应对客户不产生影响,即客户的代码不比重新编译。
你想对客户完全隐藏抽象的实现部分。
正如意图一节的第一个类图中所示的那样,有许多类要生成。这样一种类层次结构说明你必须将一个对象分成两个部分。
你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。[/size]
[size=large]5、结构[/size]
[img]http://dl.iteye.com/upload/attachment/0082/2727/8ed2a122-f613-3548-8f07-f02cec867f8d.jpg[/img]
[size=large]6、代码示例[/size]
The following Java (SE 6) program illustrates the 'shape' example given below and will output:

API1.circle at 1.000000:2.000000 radius 7.5000000
API2.circle at 5.000000:7.000000 radius 27.500000

/** "Implementor" */
interface DrawingAPI {
public void drawCircle(double x, double y, double radius);
}

/** "ConcreteImplementor" 1/2 */
class DrawingAPI1 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %f:%f radius %f\n", x, y, radius);
}
}

/** "ConcreteImplementor" 2/2 */
class DrawingAPI2 implements DrawingAPI {
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %f:%f radius %f\n", x, y, radius);
}
}

/** "Abstraction" */
abstract class Shape {
protected DrawingAPI drawingAPI;

protected Shape(DrawingAPI drawingAPI){
this.drawingAPI = drawingAPI;
}

public abstract void draw(); // low-level
public abstract void resizeByPercentage(double pct); // high-level
}

/** "Refined Abstraction" */
class CircleShape extends Shape {
private double x, y, radius;
public CircleShape(double x, double y, double radius, DrawingAPI drawingAPI) {
super(drawingAPI);
this.x = x; this.y = y; this.radius = radius;
}

// low-level i.e. Implementation specific
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
// high-level i.e. Abstraction specific
public void resizeByPercentage(double pct) {
radius *= pct;
}
}

/** "Client" */
class BridgePattern {
public static void main(String[] args) {
Shape[] shapes = new Shape[] {
new CircleShape(1, 2, 3, new DrawingAPI1()),
new CircleShape(5, 7, 11, new DrawingAPI2()),
};

for (Shape shape : shapes) {
shape.resizeByPercentage(2.5);
shape.draw();
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值