设计模式
对象创建
1. AbstractFactory -
提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
就上面的图而言,存在一系列一览关系的是ProductA1-ProductB1, ProductA2和ProductB2,视频中讲的这种关系是创建数据库和连接数据库的关系。
#include <iostream>
using namespace std;
//--------------产品类型的抽象基类
class AbstractProductA {
public:
virtual ~AbstractProductA(){ }
protected:
AbstractProductA(){}
};
class AbstractProductB{
public:
virtual ~AbstractProductB(){}
protected:
AbstractProductB(){}
};
//--------------产品的实例类
class ProductA1 : public AbstractProductA
{
public:
ProductA1(){
cout << "ProductA1()" <<endl;
}
~ProductA1(){}
};
class ProductA2 : public AbstractProductA
{
public:
ProductA2(){
cout << "ProductA2()" <<endl;
}
~ProductA2(){}
};
class ProductB1 : public AbstractProductB
{
public:
ProductB1(){
cout << "ProductB1()" <<endl;
}
~ProductB1(){}
};
class ProductB2 : public AbstractProductB
{
public:
ProductB2(){
cout << "ProductB2()" <<endl;
}
~ProductB2(){}
};
//------------抽象工厂
class AbstractFactory{
public:
virtual ~AbstractFactory(){}
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
protected:
AbstractFactory(){}
};
class ConcreteFactory1 : public AbstractFactory
{
public:
ConcreteFactory1(){}
~ConcreteFactory1(){}
AbstractProductA * CreateProductA(){
return new ProductA1();
}
AbstractProductB * CreateProductB(){
return new ProductB1();
}
};
class ConcreteFactory2 : public AbstractFactory
{
public:
ConcreteFactory2(){}
~ConcreteFactory2(){}
AbstractProductA * CreateProductA(){
return new ProductA2();
}
AbstractProductB * CreateProductB() {
return new ProductB2();
}
};
int main(int argc, char* argv[])
{
AbstractFactory* cf1 = new ConcreteFactory1();
cf1->CreateProductA();
cf1->CreateProductB();
return 0;
}
2. Prototype - 原型模式
使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象
#include <iostream>
using namespace std;
class Prototype
{
public:
virtual ~Prototype(){}
virtual Prototype* Clone() const = 0;
protected:
Prototype(){}
};
class ConcretePrototype : public Prototype
{
public:
ConcretePrototype(){}
ConcretePrototype(const ConcretePrototype &cp){
cout << "ConcretePrototype copy..." << endl;
}
~ConcretePrototype(){}
Prototype* Clone() const {
return new ConcretePrototype(*this);
}
};
int main(int argc, char *argv[])
{
Prototype *p = new ConcretePrototype();
Prototype* p1 = p->Clone();
return 0;
}
3. Builder - 构建器
将一个复杂对象的构建与其表示相分离,使得同样的构建过 程(稳定)可以创建不同的表示(变化)。
主要思想就是使用一个构造器,创建出这个对象,并且把这个对象提前做的一些准备进行构建,然后把这个构建成功的对象返回出来
实现复杂的构想过程,和直接使用的过程分离,解耦,提高可扩展性
#include <iostream>
using namespace std;
class Product
{
public:
Product(){
ProducePart();
cout << "return a product" << endl;
}
~Product(){}
void ProducePart(){
cout << "build part of product.." << endl;
}
};
class Builder
{
public:
virtual ~Builder(){}
virtual void BuildPartA(const string &buildPara) = 0;
virtual void BuildPartB(const string &buildPara) = 0;
virtual void BuildPartC(const string &buildPara) = 0;
virtual Product * GetProduct() = 0;
protected:
Builder(){}
};
class ConcreteBuilder : public Builder
{
public:
ConcreteBuilder(){}
~ConcreteBuilder(){}
virtual void BuildPartA(const string &buildPara) {
cout << "Step1: Builder PartA..." << buildPara << endl;
}
virtual void BuildPartB(const string &buildPara) {
cout << "Step1: Builder PartB..." << buildPara << endl;
}
virtual void BuildPartC(const string &buildPara) {
cout << "Step1: Builder PartC..." << buildPara << endl;
}
virtual Product * GetProduct() {
BuildPartA("pre-defined");
BuildPartB("pre-defined");
BuildPartC("pre-defined");
return new Product();
}
};
class Director
{
public:
Director(Builder *bld)
:_bld(bld){
}
~Director(){}
void Construct(){
_bld->BuildPartA("user-defined");
_bld->BuildPartB("user-defined");
_bld->BuildPartC("user-defined");
}
private:
Builder* _bld;
};
int main(int argc, char *argv[])
{
Builder *b = new ConcreteBuilder();
Director *d = new Director(b);
d->Construct();
Product *p = b->GetProduct();
return 0;
}
接口隔离
1. Facade - 门面模式
为子系统中的一组接口 供一个一致(稳定)的界面, Façade模式定义了一个高层接口,这个接口使得这一子系统 更加容易使用(复用)。
#include <iostream>
using namespace std;
class Subsystem1{
public:
Subsystem1(){}
~Subsystem1(){}
void Operation(){
cout << "Subsystem1 operation" << endl;
}
};
class Subsystem2{
public:
Subsystem2(){}
~Subsystem2(){}
void Operation(){
cout << "Subsystem2 operation" << endl;
}
};
class Facade
{
public:
Facade(){
this->_sub1 = new Subsystem1();
this->_sub2 = new Subsystem2();
}
~Facade(){
delete _sub1;
delete _sub2;
}
void OperationWrapper(){
this->_sub1->Operation();
this->_sub2->Operation();
}
private:
Subsystem1* _sub1;
Subsystem2* _sub2;
};
int main(int argc, char*argv[])
{
Facade *f = new Facade();
f->OperationWrapper();
return 0;
}
2. Proxy - 代理模式
至少在以下集中情况下可以用 Proxy 模式解决问题:
1)创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理 去完成,GoF 称之为虚代理(Virtual Proxy);
2)为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网 络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成,GoF 称 之为远程代理(Remote Proxy);
3)对对象进行控制访问的时候,比如在 Jive 论坛中不同权限的用户(如管理员a、普通 用户等)将获得不同层次的操作权限,我们将这个工作交给一个代理去完成,GoF 称之为保 护代理(Protection Proxy)。
#include <iostream>
using namespace std;
class Subject{
public:
virtual ~Subject(){}
virtual void Request() = 0;
protected:
Subject(){}
};
class ConcreteSubject : public Subject
{
public:
ConcreteSubject(){}
~ConcreteSubject(){}
void Request(){
cout << "ConcreteSubject ...request" <<endl;
}
};
class Proxy
{
public:
Proxy(Subject* sub)
:_sub(sub){}
~Proxy(){}
void Request(){
cout << "Proxy request..." << endl;
_sub->Request();
}
private:
Subject *_sub;
};
int main(int argc, char *argv[])
{
Subject *sub = new ConcreteSubject();
Proxy* p = new Proxy(sub);
p->Request();
return 0;
}
3. Adapter - 适配器
将一个类的接口转换成客户希望的另一个接口。Adapter模 式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
#include <iostream>
using namespace std;
class Target{
public:
Target(){}
virtual ~Target(){}
virtual void Request(){
cout << "Target::Request"<<endl;
}
};
class Adaptee{
public:
Adaptee(){}
~Adaptee(){}
void SpecificRequest(){
cout << "Adaptee::SpecificRequest" << endl;
}
};
class Adapter : public Target
{
public:
Adapter(Adaptee* ade)
:_ade(ade){}
~Adapter(){}
void Request(){
_ade->SpecificRequest();
}
private:
Adaptee* _ade;
};
int main(int argc ,char* argv[])
{
Adaptee* ade = new Adaptee;
Target* adt = new Adapter(ade);
adt->Request();
return 0;
}
4. Mediator - 中介者
用一个中介对象类封装(封装变化)一系列的对象交互。
中介者使各个对象不需要显式的相互引用(编译时依赖-> 运行时依赖),从而使其耦合松散,而且可以独立的改变他们之间的变化
#include <iostream>
#include <string>
using namespace std;
class Mediator;
class Colleage
{
public:
virtual ~Colleage(){}
virtual void Action() = 0;
virtual void SetState(const string &std) = 0;
virtual string GetState() = 0;
protected:
Colleage(){}
Colleage(Mediator *mdt)
:_mdt(mdt){}
Mediator *_mdt;
};
class Mediator
{
public:
virtual ~Mediator(){}
virtual void DoActionFromAtoB() = 0;
virtual void DoActionFromBtoA() = 0;
protected:
Mediator(){}
};
class ConcreteColleageA : public Colleage
{
public:
ConcreteColleageA(){}
ConcreteColleageA(Mediator* mdt)
: Colleage(mdt){
}
~ConcreteColleageA(){}
void Action(){
_mdt->DoActionFromAtoB();
cout << "state of ConcreteColleageA:" << this->GetState() << endl;
}
void SetState(const string& sdt){
_sdt = sdt;
}
string GetState(){
return _sdt;
}
private:
string _sdt;
};
class ConcreteColleageB : public Colleage
{
public:
ConcreteColleageB(){}
ConcreteColleageB(Mediator* mdt)
: Colleage(mdt){
}
~ConcreteColleageB(){}
void Action(){
_mdt->DoActionFromAtoB();
cout << "state of ConcreteColleageB:" << this->GetState() << endl;
}
void SetState(const string& sdt){
_sdt = sdt;
}
string GetState(){
return _sdt;
}
private:
string _sdt;
};
class ConcreteMediator : public Mediator
{
public:
ConcreteMediator(){}
ConcreteMediator(Colleage* clgA, Colleage*clgB)
:_clgA(clgA),_clgB(clgB)
{}
~ConcreteMediator(){}
void SetConcreteColleageA(Colleage* clgA){
_clgA = clgA;
}
void SetConcreteColleageB(Colleage* clgB){
_clgB = clgB;
}
Colleage* GetConcreteColleageA(){
return _clgA;
}
Colleage* GetConcreteColleageB(){
return _clgB;
}
void IntroColleage(Colleage* clgA, Colleage* clgB)
{
this->_clgA = clgA;
this->_clgB = clgB;
}
void DoActionFromAtoB(){
_clgB->SetState(_clgA->GetState());
}
void DoActionFromBtoA(){
_clgA->SetState(_clgB->GetState());
}
private:
Colleage* _clgA;
Colleage* _clgB;
};
int main(int argc, char *argv[])
{
ConcreteMediator* m = new ConcreteMediator();
ConcreteColleageA* c1 = new ConcreteColleageA(m);
ConcreteColleageB* c2 = new ConcreteColleageB(m);
m->IntroColleage(c1, c2);
c1->SetState("old");
c2->SetState("old");
c1->Action();
c2->Action();
cout << endl;
c1->SetState("new");
c1->Action();
c2->Action();
cout << endl;
c2->SetState("old");
c2->Action();
c2->Action();
return 0;
}
Mediator 模式的实现关键就是将对象 Colleague 之间的通信封装到一个类种单独处理,
为了模拟 Mediator 模式的功能,这里给每个 Colleague 对象一个 string 型别以记录其状态, 并通过状态改变来演示对象之间的交互和通信。这里主要就 Mediator 的示例运行结果给出 分析:
1)将 ConcreteColleageA 对象设置状态“old”,ConcreteColleageB 也设置状态“old”;
2)ConcreteColleageA 对象改变状态,并在 Action 中和 ConcreteColleageB 对象进行通信,并改变 ConcreteColleageB 对象的状态为“new”;
3)ConcreteColleageB 对象改变状态,并在 Action 中和 ConcreteColleageA 对象进行通信,并改变 ConcreteColleageA 对象的状态为“new”;
注意到,两个 Colleague 对象并不知道它交互的对象,并且也不是显示地处理交互过程,这一切都是 通过 Mediator 对象完成的,示例程序运行的结果也正是证明了这一点。