设计模式之八:Bridge(桥接)—对象结构型模式

来源:互联网 发布:pp助手mac 导不了铃声 编辑:程序博客网 时间:2024/06/05 21:53

22:01:24 星期一 22:01:37 

Bridge,继续GOF。博客园 设计模式之八:Bridge(桥接)—对象结构型模式

和Stratege模式相比,Bridge可以说是“包含Stratege”。

Stratege : 1个物件对应N个实现。仅 实现端(类) 有细分。

Bridge    : M个物件对应N个实现。抽象端(类) 和 实现端(类) 都有细分。

1、Intent

Decouple an abstraction from its implementation so that the two can vary independently.

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

2、Also Known As

Handle/Body

3、Motivation

When an abstraction can have one of several possible implementations, the usual way to accommodate them is to use inheritance. An abstract class defines the interface to the abstraction, and concrete subclasses implement it in different ways. But this approach isn't always flexible enough. Inheritance binds an implementation to the abstraction permanently, which makes it difficult to modify, extend, and reuse abstractions and implementations independently.

当一个抽象可能有多个实现时,通常用继承来协调它们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但是此方法有时不够灵活。继承机制将抽象部分与它的实现部分固定在一起,使得难以对抽象部分和实现部分独立地进行修改、扩充和重用。

● 未使用Bridge的,抽象和实现未分离。




● 使用Bridge的,抽象和实现分离。使用2个类来描述。



Bridge的魅力在于抽象和实现之间是松散的关系,它们之间可以进行随意组合。如上图中,就有IconWindow+XWindowImp、TransientWindow+XWindowImp、IconWindow+PMWindowImp、TransientWindow+PMWindowImp四种组合。

4、Applicability

Use the Bridge pattern when

●  you want to avoid a permanent binding between an abstraction and its implementation. This might be the case, for example, when the implementation must be selected or switched at run-time.

●  both the abstractions and their implementations should be extensible by subclassing. In this case, the Bridge pattern lets you combine the different abstractions and implementations and extend them independently.

●  changes in the implementation of an abstraction should have no impact on clients; that is, their code should not have to be recompiled.

●  (C++) you want to hide the implementation of an abstraction completely from clients. In C++ the representation of a class is visible in the class interface.

●  you have a proliferation of classes as shown earlier in the first Motivation diagram. Such a class hierarchy indicates the need for splitting an object into two parts. Rumbaugh uses the term "nested generalizations" [RBP+91] to refer to such class hierarchies.

●  you want to share an implementation among multiple objects (perhaps using reference counting), and this fact should be hidden from the client. A simple example is Coplien's String class [Cop92], in which multiple objects can share the same string representation (StringRep).

在以下情况使用Bridge模式:

 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。 例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。

 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时 B r i d g e模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

  对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。

 (C + +)你想对客户完全隐藏抽象的实现部分。在 C + +中,类的表示在类接口中是可见的。

 正如在意图一节的第一个类图中所示的那样,有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。 R u m b a u g h称这种类层次结构为“嵌套的普化”(nested generalizations) 。

 你想在多个对象间共享实现(可能使用引用计数) ,但同时要求客户并不知道这一点。一个简单的例子便是 C o p l i e n的S t r i n g类[ C o p 9 2 ],在这个类中多个对象可以共享同一个字符串表示( S t r i n g R e p) 。

5、Structure

6、代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#if 1
      
    // class Implementor
    class Implementor
    {
    public:
        virtual void OperationImp() = 0 ;
    };
  
    // class ConcreteImplementorA
    class ConcreteImplementorA : public Implementor
    {
    public:
        virtual void OperationImp() {}
    };
      
    // class ConcreteImplementorB
    class ConcreteImplementorB : public Implementor
    {
    public:
        virtual void OperationImp() {}
    };
      
    // class Abstraction
    class Abstraction
    {
    public:
        void Operation(Implementor* imp) {assert(imp); imp->OperationImp();}
    };
      
    // class ConcreteAbstractionA
    class ConcreteAbstractionA : public Abstraction
    {
    public:
        void OperationA(Implementor* imp) {Operation(imp);}
    };
  
    //客户端代码:
    void Bridge_Demo()
    {
        Abstraction obj;
        Implementor *impa = new ConcreteImplementorA();
        Implementor *impb = new ConcreteImplementorB();
        obj.Operation(impa); //第一种实现方法
        obj.Operation(impb); //第二种实现方法
  
        ConcreteAbstractionA objA;
        objA.OperationA(impb);
    }
  
#endif
0 0