为什么要使用 bridge 模式?


 

意图:将抽象部分与实现部分分离 ,使他们都可以独立变化

 估计大家看了这个意图后,基本是不明白在说什么,分离 是指 它们能够独立变化,或者有一定的弱耦合。抽象呢 “存在于多个实体中的概念性的联系” 多个对象如果具有相同的概念性联系,那么它们就可以通过一个共同的类来描述,如果一些类具有共同的概念性联系 那么可以通过一个共同的抽象类来描述。以上是 阎宏说的 ,应该比较好理解 。

实现呢? 我开始简单的理解为 抽象的具体类,其实 并不是这样 ,实现化也可以是与抽象化等级结构相平行的等级结构,同样可以有抽象类和具体类组成 (阎宏)

我想对于这点的理解很关键,抽象与实现应该更宏观的理解 ,这样才能理解桥接模式 。

 为什么使用?

1:可能一开始,你的继承体系 很好  没有任何问题,但变化是无处不在的,过了一段时间,抽象 处 发生了变化,使得类型有两个以上的纬度变化,于是我们就 封装变化,形成一个新的继承体系结构,在抽象与实现之间用聚合来联系他们 。

2:抽象与实现一般用一个继承体系来实现(我们经常这样做 不是吗?)抽象角色封装了抽象的业务逻辑,系统中的不变的部分(要不 怎么说是抽象呢,抽象的东西一般都比较稳定 。)第二层是 实现角色,封装了会变化的部分。允许实现化角色多态性变化。恩,以上很好理解 是吗?一个继承体系就只处理一个变化。但 如果这时抽象角色再变化了呢? 怎么办 ?呵呵 那就需要一个新的继承体系。 这两个继承体系 怎么联系呢? 聚合 !

3:可能有人说 为什么我一个继承体系 也能实现,是的,但 那样 不符合职责单一 而且 继承的过多使用 导致 代码重复 修改困难 。

现实中的应用

   在网络通讯中由于需要对各种类型的事件进行多路分离和进行相应的实现,有过通讯编程经验的人都知道,每种平台下都有几种不同的实现,针对以上的情况 ACE 中 ACE_Reactor就应用了本模式,它把实现与抽象进行了分离。针对不同的实现有不同的实现类 如 ACE_Select_Reactor和ACE_WFMO_Reactor.

ACE_Reactor 定义抽象类的接口 它里面维护一个指针reactor_impl_,指向Implementor类型的一个对象。ACE_Reactor 就扮演本模式中的 Abstraction

角色, ACE_Reactor_Impl定义Reactor实现类的接口扮演Implementor角色,当然ACE_Select_Reactor_Impl和ACE_WFMO_Reactor 实现Reactor_Impl接口,并定义其具体实现 扮演ConcreteImplementor角色

源码为证:

class ACE_Export ACE_Reactor : public ACE_Reactor_Timer_Interface

{

public:

 /// Operations on the "ready" mask and the "dispatch" mask.

 

 int register_handler (const ACE_Handle_Set &handles,

                        ACE_Event_Handler *event_handler,

                        ACE_Reactor_Mask masks);

protected:

 /// Set the implementation class.

 void implementation (ACE_Reactor_Impl *implementation);

 

 /// Delegation/implementation class that all methods will be

 /// forwarded to.

 ACE_Reactor_Impl *implementation_;   //指向实现

class ACE_Export ACE_Select_Reactor_Impl : public ACE_Reactor_Impl

{

public:

 enum

 {

    /// Default size of the Select_Reactor's handle table.

    DEFAULT_SIZE = ACE_DEFAULT_SELECT_REACTOR_SIZE

 };

}

当然,这个例子中并没有实现 RefinedAbstraction角色。这样是不是就用实现来继承抽象接口呢?肯定不行 第一:这样导致类过大,第二:不符合职责单一原则,第三:逻辑不清晰,维护起来麻烦多多。第四:还记的吗?聚合优先继承。

注: 以上的代码 我并没有帖全,如果你想看的话 可以在Reactor.h和Select_Reactor_T.h等文件中找到。

 


 

 

posted @ 2008-12-15 17:43  wangok  阅读(417)  评论(2)    收藏  举报