您的位置:首页 > 其它

设计模式二,Proxy,State,Adapter,Template Method

2011-01-08 12:35 288 查看
Proxy,可以理解为本身不提供实现方式,通过接口调用具体的实现。
//:C10:ProxyDemo.cpp
//SimpledemonstrationoftheProxypattern.
#include<iostream>
usingnamespacestd;
classProxyBase{
public:
virtualvoidf()=0;
virtualvoidg()=0;
virtualvoidh()=0;
virtual~ProxyBase(){}
};
classImplementation:publicProxyBase{
public:
voidf(){cout<<"Implementation.f()"<<endl;}
voidg(){cout<<"Implementation.g()"<<endl;}
voidh(){cout<<"Implementation.h()"<<endl;}
};
classProxy:publicProxyBase{
ProxyBase*implementation;
public:
Proxy(){implementation=newImplementation();}
~Proxy(){deleteimplementation;}
//Forwardcallstotheimplementation:
voidf(){implementation->f();}
voidg(){implementation->g();}
voidh(){implementation->h();}
};
intmain(){
Proxyp;
p.f();
p.g();
p.h();
}///:~

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}



state:改变对象的行为

状态模式产生一个可以改变其类的对象,当发现在大多数或者所有函数中都存在有条件的代码时,这种模式很有用。和代理模式一样,状态模式通过一个前端对象来使用后端实现对象履行其职责。然而,在前端对象生存期期间,状态模式从一个实现对象到另一个实现对象进行切换,以实现对于相同的函数调用产生不同的行为。

需要使用state模式的情境:

//:C10:KissingPrincess.cpp
#include<iostream>
usingnamespacestd;
classCreature{
boolisFrog;
public:
Creature():isFrog(true){}
voidgreet(){
if(isFrog)
cout<<"Ribbet!"<<endl;
else
cout<<"Darling!"<<endl;
}
voidkiss(){isFrog=false;}
};
intmain(){
Creaturecreature;
creature.greet();
creature.kiss();
creature.greet();
}///:~
然而,greet()等任何其他所有函数在执行操作前都必须测试变量isFrog,这样就使代码变
得笨拙至极,特别是在系统中加入额外的状态时情况会更加严重。通过将操作委派给状态对
象,这种情况就可以改变,代码从而得到了简化。

//:C10:KissingPrincess2.cpp
//TheStatepattern.
#include<iostream>
#include<string>
usingnamespacestd;
classCreature{
classState{
public:
virtualstringresponse()=0;
};
classFrog:publicState{
public:
stringresponse(){return"Ribbet!";}
};
classPrince:publicState{
public:
stringresponse(){return"Darling!";}
};
State*state;
public:
Creature():state(newFrog()){}
voidgreet(){
cout<<state->response()<<endl;
}
voidkiss(){
deletestate;
state=newPrince();
}
};
intmain(){
Creaturecreature;
creature.greet();
creature.kiss();
creature.greet();
}///:~

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}


.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

在这里,将实现类设计为嵌套或者私有并不是必需的,但是如果能做到的话,就会创建出更加清晰的代码。

注意,对状态类的改变将会自动地在所有的代码中进行传播,而不需要编辑这些类来完成改变。

Adapter:适配器模式接受一种类型并且提供一个对其他类型的接口。当给定一个库或者具有某一接口的一段代码,同时还给定另外一个库或者与前面那段代码的基本思想相同的一段代码而只是表达方式不一致时,适配器模式将十分有用。通过调整彼此的表达方式以适配彼此,将会迅速产生解决方法。

以下代码比较复杂,一时还未参透,记下来再说:



classFibonacciGenerator{
intn;
intval[2];
public:
FibonacciGenerator():n(0){val[0]=val[1]=0;}
intoperator()(){
intresult=n>2?val[0]+val[1]:n>0?1:0;
++n;
val[0]=val[1];
val[1]=result;
returnresult;
}
intcount(){returnn;}
};
//:C10:FibonacciAdapter.cpp
//Adaptinganinterfacetosomethingyoualreadyhave.
#include<iostream>
#include<numeric>
//#include"FibonacciGenerator.h"
#include"../PrintSequence.h"
usingnamespacestd;
classFibonacciAdapter{//Produceaniterator
FibonacciGeneratorf;
intlength;
public:
FibonacciAdapter(intsize):length(size){}
classiterator;
friendclassiterator;
classiterator:publicstd::iterator<
std::input_iterator_tag,FibonacciAdapter,ptrdiff_t>{
FibonacciAdapter≈
public:
typedefintvalue_type;
iterator(FibonacciAdapter&a):ap(a){}
booloperator==(constiterator&)const{
returnap.f.count()==ap.length;
}
booloperator!=(constiterator&x)const{
return!(*this==x);
}
intoperator*()const{returnap.f();}
iterator&operator++(){return*this;}
iteratoroperator++(int){return*this;}
};
iteratorbegin(){returniterator(*this);}
iteratorend(){returniterator(*this);}
};
intmain(){
constintSZ=20;
FibonacciAdaptera1(SZ);
cout<<"accumulate:"
<<accumulate(a1.begin(),a1.end(),0)<<endl;
FibonacciAdaptera2(SZ),a3(SZ);
cout<<"innerproduct:"
<<inner_product(a2.begin(),a2.end(),a3.begin(),0)
<<endl;
FibonacciAdaptera4(SZ);
intr1[SZ]={0};
int*end=partial_sum(a4.begin(),a4.end(),r1);
print(r1,end,"partial_sum","");
FibonacciAdaptera5(SZ);
intr2[SZ]={0};
end=adjacent_difference(a5.begin(),a5.end(),r2);
print(r2,end,"adjacent_difference","");
}///:~

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

TemplateMethod:

模板方法模式的一个重要特征是它的定义在基类中(有时作为一个私有成员函数)并且不能改动。

//:C10:TemplateMethod.cpp
//SimpledemonstrationofTemplateMethod.
#include<iostream>
usingnamespacestd;
classApplicationFramework{
protected:
virtualvoidcustomize1()=0;
virtualvoidcustomize2()=0;
public:
voidtemplateMethod(){
for(inti=0;i<5;i++){
customize1();
customize2();
}
}
};
//Createanew"application":
classMyApp:publicApplicationFramework{
protected:
voidcustomize1(){cout<<"Hello";}
voidcustomize2(){cout<<"World!"<<endl;}
};
intmain(){
MyAppapp;
app.templateMethod();
}///:~

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

驱动应用程序运行的“引擎”是模板方法模式。在GUI(图形用户界面)应用程序中,这个“引擎”就是主要的事件环,客户程序员只需提供customize1()和customise2()的定义,便可以令“应用程序”运行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: