Chinaunix首页 | 论坛 | 博客
  • 博客访问: 348748
  • 博文数量: 88
  • 博客积分: 1695
  • 博客等级: 上尉
  • 技术积分: 1380
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-06 15:48
个人简介

喜欢美食, 旅行..

文章分类

全部博文(88)

文章存档

2014年(2)

2013年(12)

2012年(14)

2010年(8)

2009年(52)

我的朋友

分类: C/C++

2013-02-07 12:06:52

1. 意图

将抽象部分与它的实现部分分离, 使它们都可以独立变化, 相比继承而言有更大的灵活度.

2. 面向对象设计原则

好莱坞原则:别调用我, 我会调用你的. ( 防止依赖腐败, 只能让 Handle 调用 Body ). 

3. 适用性

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

* 类的抽象以及它的子类都可以通过生成子类的方式扩充. 这时 Bridge 模式可以使你对不同的抽象接口和实现部分组合, 并分别对它们扩充.

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

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

* 你有许多的子类要生成, 必须将一个对象一分为二以实现 "嵌套的普化" ( Nested generalizations ). 

* 你想在多个对象间共享实现 ( 可能使用引用计数 ), 但同时要求客户并不知道这一点. 

4. 类层次结构图

5. 实现

使用 Bridge 模式的时候需要注意下面几点:

* 仅有一个实现的时候, 没有必要创建一个抽象的 Implementor 类. 这是 Bridge 的退化情况, 在 Abstraction 和 Implementor 之间有一种一对一的关系.

* 当存在多个 Implementor 类的时候, 你可以尝试下面的方式:

   a. 如果 Abstraction 知道所有的 ConcreteImplementor, 它就可以在它的构造器中对其中的一个进行实例化, 它可以通过传递给构造器的参数确定应该实例化哪一个. 

   b. 首先选择一个缺省的实现, 然后根据需要 ( 缺省实现不能满足需求的时候 ) 改变这个实现. 

   c. 代理给另一个对象, 让它一次性决定. 例如, 我们可以引入一个 Factory 对象 ( 抽象工厂设计模式 ), 该对象的唯一职责就是创建各种 ConcreteImplementor.

* 共享 Implementor 的时候, 需要实现一个对象引用计数器. 和智能指针 shared_ptr 的实现原理类似.

* C++ 中可以使用多重继承机制将抽象接口和它的实现部分结合起来. 例如, 一个类可以使用 public 方式继承 Abstraction 而以 private 方式继承 ConcreteImplementor. 但是, 由于这种方法依赖于静态继承, 它将实现部分与接口部分固定不变的绑定在一起, 因此, 不可能使用多重继承实现真正的 Bridge 模式, 至少用 C++ 不行.

6. 样例代码

估计网友看完上面的长篇大论快要骂娘了. 下面附上一份简单的实现, 希望共勉之.

// Animal.h

#include"AnimalImp.h"
class Animal
{
protected: template
    AnimalImp * GetAnimalImp() { return new TypeAnimalImp; }
public:
    Animal() { }
    virtual ~Animal() { }
    virtual void MusicAction() = 0;
};

//AnimalImp.h

class AnimalImp 
{
public:
    AnimalImp() { }
    virtual ~AnimalImp() { }
    virtual void StandUp() = 0;
    virtual void Dancing() = 0;
    virtual void Singing() = 0;
};

// Duck.h

#include “Animal.h”
#include “DuckImp.h”
class Duck : public Animal
{
public:
    Duck(){  }
    virtual ~Duck(){}

    virtual void MusicAction()
    {
        AnimalImp * ptrImp = GetAnimalImp();
        ptrImp->StandUp();
        size_t time = 10;
        while( --time > 0 )
        {
            ptrImp->Dancing();
            ptrImp->Singing();
            ptrImp->Singing();
        }
        delete ptrImp;
    }
};

// DuckImp.h

#include 
#include "AnimalImp.h"
class DuckImp : public AnimalImp
{ public:
    DuckImp() : AnimalImp(){}
    virtual ~DuckImp(){}
    virtual void StandUp(){ cout << " the duck stand up. " << endl; }
    virtual void Dancing(){ cout << " the duck rickety shuttlecock. " << endl; }
    virtual void Singing(){ cout << " the duck sings : ga~ga~ga~~. " << endl; }
};

// Dog.h

#include "Animal.h"
#include "DogImp"
class Dog : public Animal
{
public:
    Dog() { }
    virtual ~Dog() { }
    virtual void MusicAction()
    {
        AnimalImp * ptrImp = GetAnimalImp();
        ptrImp->StandUp();
        size_t time = 10;
        while( --time > 0 )
        {
            ptrImp->Dancing();
            ptrImp->Dancing();
            ptrImp->Singing();
        }
        delete ptrImp;
    }
};

// DogImp.h

#include 
class DogImp : public AnimalImp
{
public:
    DogImp() : AnimalImp(){}
    virtual ~DogImp(){}
    virtual void StandUp(){ cout << " the dog stand up. " << endl; }
    virtual void Dancing(){ cout << " the dog run and run. " << endl; }
    virtual void Singing(){ cout << " the dog sings : wang~wang~wang~~. " << endl; }
};

// main.cpp

#include "Dog.h"
#include "Duck.h"
void main()
{
    Duck animal;
    animal.MusicAction();
    Dog animal2;
    animal2.MusicAction();
}


阅读(3446) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~