设计模式(6)-桥接(Bridge)模式

来源:互联网 发布:sql中时间戳转换 编辑:程序博客网 时间:2024/06/15 15:44

将抽象与实现分离,使其双方独立变化是桥接模式的意图。

当一个抽象类可能有多个实现时,通常用继承协调他们。抽象类定义对该抽象的接口,而具体的子类则用不同方式加以实现。但抽象和实现在这种设计下是绑定的,不能灵活的改变,利用和扩展。桥接模式的出现就是要解耦这种关系。

场景

桥接模式的重点在于抽象与实现的解耦合,所以设想这样一个场景。一个抽象接口的实例需要动态的根据需求具有不同的实现。这一点通过继承显然不能真正的满足,采用桥接模式,动态的将不同的实现赋予这个实例,使他在运行时,根据自身需求,具有不同的实现。这样的例子可以很好的体现抽象与实现分离的特点。

结构

这里写图片描述

实现

实现要点:
抽象与实现分为两种类,互相不相关;
抽象基类维护一个实现基类指针,用来指向实现方法;
抽象基类记得为维护的引用提供可访问的方法;
实现时,将基类的请求转接到实现类的引用实例即可。

Class Abstraction
{
Public:
virtual void operation1(){_implementor->operation1();};
virtual void operation2(){_implementor->operation2();};
virutal ~Abstraction();
protected:
getImplementor();
setImplementor(Implementor*);
private:
Implementor* _implementor;
}
Class RefinedAbstraction:public Abstraction
{
Public:
void operation2(){_implementor->operation2();};
}

Class Implementor
{
Public:
virtual void operation1()=0;
virtual void operation2()=0;
virtual ~Implementor();
}

Class ConcreteImplementorA::public Implementor
{
Public:
virtual void operation1(){//A::operation1};
virtual void operation2(//A::operation2);
}

Class ConcreteImplementorB::public Implementor
{
Public:
virtual void operation1(){//B::operation1};
virtual void operation2(//B::operation2);
}

//调用
void main()
{
Implementor* impb=new ConcreteImplementorB();
Implementor* impa=new ConcreteImplementorA();
Abstraction *abs=new RefinedAbstraction();
abs->setImplementor(impb);//将B类作为实现
abs->operation1();//调用B::operation1
abs->setImplementor(impa);//将A类作为实现
abs->operation1();//调用A::operation1
}

优点

  • 接口与实现的分离
    实现与接口不再绑定,在客户维护一个实现基类的情况下,甚至可以在运行时改变实现。
  • 可扩展性提高
    基于接口与实现的分离,可以独立的对接口和实现进行改变,只要最后转接到的实现正确即可。
  • 完全隐藏具体实现
    客户只看到一个又一个的接口基类,并不知道实现基类做了什么。

思考

桥接模式作为一种类协同的工作模式,似乎与Adapter模式有很多相似的地方,这两者本质上有什么不同呢?

  • Adapter模式用来帮助无关类的协同工作,而桥接模式用来解耦抽象与实现,桥接模式是帮助相关类的协同;

  • Adapter是对设计失误或者遗留类的补救或者补充,而桥接是一种使系统更健壮的设计;

综合来看,Adapter是被动选择,而桥接模式是主动的设计,前者使无关的类协同,后者为了使类具有更高的扩展性和可维护性。桥接模式是非常优秀的设计,缺点可能就是比继承复杂了一点儿。