至此,创建型模式的学习告一段落,现在开始的是结构型模式。
C++设计,面向对象设计都一直在强调高内聚,低耦合。Bridge将是一个非常有价值的模式。当然Bridge也是一个比较不好理解的例子,写到此处为止,笔者依然不能有非常清晰逻辑,只是搞清楚了实现方法。希望等结束文章时候能有所提升。
桥接模式:将抽象化Abstraction和实现化Implementation分离,让实现和抽象分离。这句话,我看第一遍直接跳过了,不知所云啊~在一本设计模式的书中,讲了一个手机的例子,对于手机类,下面继承了很多品牌的手机,每个手机品牌比如摩托,诺记,苹果,三星,华为等都是一个第二层的子类,而每个手机品牌类又有继承各自的通讯录类,游戏类,QQ类等,毕竟安卓,iOS,WP系统都互不兼容所以都自建一类。当这个时候苹果手机升级,下面的软件类也需要作出一定的调整。这是很违背内聚-耦合初衷的,也不符合开放封闭原则,毕竟各个软件类又要打开修改,如果说将软件类写成抽象父类,在下面继承各个版本的子类时,结构就太庞大了。这样看来,虽然手机品牌类——苹果类、华为类有一层抽象,但是这样的设计并不人性,对于多变的更新快的手机行业是不好用的。那么,再来说分开Abstraction和Implementation就有意义了,怎么把手机类和各个软件分开呢?
先看看UML图:(或点击这里)
Abstraction和RefinedAbstraction就是抽象部分,AbstractionImplement和ConcreteImplementate就是实现部分,至于说各自都有继承,我想这也是C++设计的一种习惯,还是之前说的,多态是C++的灵魂,继承是C++的肉体,封装是皮层,指针/引用时血液。好的设计是离不开这些的。说偏了,在这个UML图中我们将实现都放在了右边的结构中ConcreteImplementate*是各种软件,左边是手机品牌,他们各自变化,可以相互保持低的影响。
代码:
//Implement
#ifndef _ABSTRACTIONIMPLEMENT_H_
#define _ABSTRACTIONIMPLEMENT_H_
class AbstractionImplement
{
public:
AbstractionImplement();
virtual ~AbstractionImplement();
virtual void operation() = 0;
};
class ConcreteAbstractionImplement1:public AbstractionImplement
{
public:
ConcreteAbstractionImplement1();
~ConcreteAbstractionImplement1();
void operation();
};
class ConcreteAbstractionImplement2:public AbstractionImplement
{
public:
ConcreteAbstractionImplement2();
~ConcreteAbstractionImplement2();
void operation();
};
#endif
#include "AbstractionImplement.h"
#include <iostream>
using namespace std;
AbstractionImplement::AbstractionImplement()
{
}
AbstractionImplement::~AbstractionImplement()
{
}
ConcreteAbstractionImplement1::ConcreteAbstractionImplement1()
{
}
ConcreteAbstractionImplement1::~ConcreteAbstractionImplement1()
{
}
void ConcreteAbstractionImplement1::operation()
{
cout<<"Implement1"<<endl;
}
ConcreteAbstractionImplement2::ConcreteAbstractionImplement2()
{
}
ConcreteAbstractionImplement2::~ConcreteAbstractionImplement2()
{
}
void ConcreteAbstractionImplement2::operation()
{
cout<<"Implement2"<<endl;
}
//Abstraction
#ifndef _ABSTRACTION_H_
#define _ABSTRACTION_H_
#include "AbstractionImplement.h"
class Abstraction
{
public:
Abstraction();
virtual ~Abstraction();
virtual void operation() = 0;
};
class RefinedAbstraction: public Abstraction
{
public:
RefinedAbstraction(AbstractionImplement* absImp);
~RefinedAbstraction();
void operation();
private:
AbstractionImplement* absImp;
};
#endif
#include "Abstraction.h"
Abstraction::Abstraction()
{
}
Abstraction::~Abstraction()
{
}
RefinedAbstraction::RefinedAbstraction(AbstractionImplement* absImp)
{
this->absImp = absImp;
}
RefinedAbstraction::~RefinedAbstraction()
{
}
void DefinedAbstraction::operation()
{
absImp->operation();
}
//client
#include "Abstraction.h"
int main()
{
AbstractionImplement* absImp1 = new ConcreteAbstractionImplement1();
Abstraction* abs1 = new RefinedAbstraction(absImp1);
abs1->operation();
AbstractionImplement* absImp2 = new ConcreteAbstractionImplement2();
Abstraction* abs2 = new RefinedAbstraction(absImp2);
abs2->operation();
return 0;
}