[GoF设计模式]Bridge模式和Template模式的C++实现

【Bridge模式】

使用组合的方式将功能的需求的抽象和实现解耦,这样一来抽象和实现可以分别独自的变化。由此解决需求变更可能带来的麻烦,即类的迅速膨胀,如一般的情况下抽象和实现可能需要M*N个类来解决问题,而使用Bridge模式则只需要M+N个类来解决问题。此处的“实现”是指“怎么实现用户的需求”,并且通过组合的方式来实现。此处的实现不是指继承基类,实现基类接口,而是通过组合实现用户的需求。Bridge模式是设计模式中复杂求难理解的模式之一。

【图解】

以中国人吃饭用筷子,美国人吃饭用叉子,当然中国人也可以用叉子吃饭,美国人也可以用筷子吃饭 为例,当然这种情况下用和不用都是定义4个类来实现的,但是当增加到三种情况下时候,运用Bridge模式只定义3+3=6个类,而不用则需要3*3需要9个类。如在加上印度人吃饭用手。简单起见,只列两个。

[GoF设计模式]Bridge模式和Template模式的C++实现_第1张图片

【程序】

/******************************************************************* * * DESCRIPTION: Person Abstraction Class [不同国家人的抽象] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef PERSONABSTRACTION_H_ #define PERSONABSTRACTION_H_ /** include files **/ #include "PersonImplement.h" class PersonAbstraction { public: /*constructor and destructor*/ PersonAbstraction(PersonImplement *personImp) { this->_personImp=personImp; } virtual ~PersonAbstraction(){} /*Have meal*/ virtual void Dining() { this->_personImp->DiningStyle(); return; } virtual void ChangeDiningStyle(PersonImplement *personImp) { this->_personImp=personImp; return; } virtual void WhereIFrom()=0; protected:/*Important*/ PersonImplement *_personImp; }; #endif  

/******************************************************************* * * DESCRIPTION:Chinese Person[中国人-对PersonAbstraction类的具体化] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef CHINESEPERSON_H_ #define CHINESEPERSON_H_ /** include files **/ #include <iostream> #include "PersonAbstraction.h" using namespace std; class ChinesePerson:public PersonAbstraction { public: /*construction and destruction*/ ChinesePerson(PersonImplement *personimp):PersonAbstraction(personimp) { } virtual ~ChinesePerson(){} virtual void WhereIFrom() { cout<<"/nChinesePerson|-->:Hi I am a Chinese."<<endl; return; } }; #endif  

/******************************************************************* * * DESCRIPTION:Americe Person [美国人-对PersonAbstraction类的具体化] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef AMERICAPERSON_H_ #define AMERICAPERSON_H_ /** include files **/ #include <iostream> #include "PersonAbstraction.h" using namespace std; class AmericaPerson:public PersonAbstraction { public: /*construction and destruction*/ AmericaPerson(PersonImplement *personImp):PersonAbstraction(personImp) { } virtual ~AmericaPerson(){} virtual void WhereIFrom() { cout<<"/nAmericaPerson|-->:Hi I am an America."<<endl; return; } }; #endif  

/******************************************************************* * * DESCRIPTION: Person Implement Class[对不通过家的人吃饭方式的抽象] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef PERSONIMPLEMENT_H_ #define PERSONIMPLEMENT_H_ class PersonImplement { public: PersonImplement(){} virtual ~PersonImplement(){} /*The Dining Implement,Different style maybe*/ virtual void DiningStyle()=0; }; #endif  

/******************************************************************* * * DESCRIPTION:Chinese Style Implement class[中国人吃饭的方式-对PersonImplement类的具体化] * * AUTHOR: Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef CHINESESTYLEIMPLEMENT_H_ #define CHINESESTYLEIMPLEMENT_H_ /** include files **/ #include <iostream> #include "PersonImplement.h" using namespace std; class ChineseStyleImplement:public PersonImplement { public: /*construction and destruction*/ ChineseStyleImplement(){} virtual ~ChineseStyleImplement(){} /*Chinese style dining*/ virtual void DiningStyle() { cout<<"I am dining with chopsticks!"<<endl;/*用筷子吃饭*/ return; } }; #endif  

/******************************************************************* * * DESCRIPTION: America Style Implement class[美国人吃饭的方式-对PersonImplement类的具体化] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef AMERICASTYLEIMPLEMENT_H_ #define AMERICASTYLEIMPLEMENT_H_ /** include files **/ #include <iostream> #include "PersonImplement.h" using namespace std; class AmericaStyleImplement:public PersonImplement { public: /*construction and destruction*/ AmericaStyleImplement(){} virtual ~AmericaStyleImplement(){} /*America style dining*/ virtual void DiningStyle() { cout<<"I am dining with fork!"<<endl;/*用叉子吃饭*/ return; } }; #endif  

/******************************************************************* * * DESCRIPTION: Bridge Pattern [桥模式] * [以中国人吃饭习惯用筷子,美国人习惯用叉子吃饭为例子] * [但是中国人也可以用叉子吃饭,美国人也可以用筷子吃饭] * AUTHOR: Neesky * * DATE:2009-9-25 * *******************************************************************/ /** include files **/ #include "ChinesePerson.h" #include "AmericaPerson.h" #include "ChineseStyleImplement.h" #include "AmericaStyleImplement.h" #include <iostream> using namespace std; int main (int argc, char *argv[]) { /*There a two style dining*/ PersonImplement *chinesestyle=new ChineseStyleImplement(); PersonImplement *americastyle=new AmericaStyleImplement(); /*Now here comes a chinese dining with chopsticks*/ ChinesePerson *chinese=new ChinesePerson(chinesestyle); chinese->WhereIFrom(); chinese->Dining(); /*Now here comes a chinese dining with chopsticks*/ AmericaPerson *america=new AmericaPerson(americastyle); america->WhereIFrom(); america->Dining(); /*Now Chinese have westlife dining with fork*/ chinese->ChangeDiningStyle(americastyle); chinese->WhereIFrom(); chinese->Dining(); america->ChangeDiningStyle(chinesestyle); america->WhereIFrom(); america->Dining(); return(0); }  

【输出】

[GoF设计模式]Bridge模式和Template模式的C++实现_第2张图片


 

【Template模式】

对于某一业务逻辑存在不同的细节实现,但总体逻辑框架是相同的。Template模式用于解决这样的问题,strategy模式和他解决的问题类似,但前者是采用集成的方式,封装的是框架,二后者采用的组合的方式,封装的算法。在Template模式中,在模板类(抽象类)的中将原子操作声明为Protected保护类型,而仅提供算法框架的函数供外界调用。

值得说明的是Template模式采用的集成方式是一种反向依赖(DIP,Dependency Inversion Principles)的方式,即父类调用了子类的接口实现(基类调用了派生类的操作)。Template模式的不足是在于其原子操作在各派生类中的细节实现不能被复用,这个问题也是继承自同一个基类说共有的问题。Strategy模式侧重在组合上,将算法封装到一个类中(如:AddOperation),并采用组合的方式解决(实现MathOperation类)。

【图解】

这个例子只做示例用,没写太具体。比如“字符串的模式匹配算法”中有KMP算法,也有前端时间知道的BM算法,这两个算法大体上满足一种逻辑框架,既用模板字符串匹配样本字符串的过程中, 首先匹配样本字符串中的字符串片段,如果没匹配成功,这由连续匹配的字符数,以及当前起始匹配的位置以及模板字符串的长度,计算出在样本字符串中的下一跳批配开始的位置,直到匹配成功。而BM算法是从模板字符串的后面向前面开始比,二KMP则是从前往后。BM和KMP算法在计算下一条位置的实现上也有所不同。以下只是Template模式的示范,并不涉及字符串模式匹配算法的具体实现。

 

【程序】

/******************************************************************* * * DESCRIPTION: String Match Algorithm Frame(字符串模式匹配算法框架) * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef STRINGMATCHALGORITHM_H_ #define STRINGMATCHALGORITHM_H_ /** include files **/ #include <iostream> using namespace std; class StringMatchAlgorithm { public: /*constructor and destructor*/ StringMatchAlgorithm(){} virtual ~StringMatchAlgorithm(){} /*The Algorithm Framework*/ virtual void ExecuteMatch() { //while()/*跳到下一个位置开始比较,简单起见,循环省略*/ CompareSection();/*在posStart位置开始匹配*/ NextPositionStartCompare();/*在不完全匹配的情况下找下一个匹配位置*/ return; } protected: /*Primitive Operations*/ virtual void CompareSection()=0; virtual void NextPositionStartCompare()=0; }; #endif  

/******************************************************************* * * DESCRIPTION: BoyerMoores String Match Algorithm[字符串的BM匹配算法] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef BMSTRINGMATCHALGORITHM_H_ #define BMSTRINGMATCHALGORITHM_H_ /** include files **/ #include "StringMatchAlgorithm.h" class BMStringMatchAlgorithm:public StringMatchAlgorithm { public: /*construction and destruction*/ BMStringMatchAlgorithm(){} virtual ~BMStringMatchAlgorithm(){} protected: /*Primitive Operations*/ virtual void CompareSection() { cout<<"/nBM String Algorithm|--->: Compare Section[primitive]......."<<endl; return; } virtual void NextPositionStartCompare() { cout<<"BM String Algorithm|--->: Jump to the next postion[primitive]......"<<endl; return; } }; #endif  

/******************************************************************* * * DESCRIPTION: KMP String Match Algorithm[字符串的KMP匹配算法] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ #ifndef KMPSTRINGMATCHALGORITHM_H_ #define KMPSTRINGMATCHALGORITHM_H_ /** include files **/ #include "StringMatchAlgorithm.h" class KMPStringMatchAlgorithm:public StringMatchAlgorithm { public: /*construction and destruction*/ KMPStringMatchAlgorithm(){} virtual ~KMPStringMatchAlgorithm(){} protected: /*Primitive Operations*/ virtual void CompareSection() { cout<<"/nKMP String Algorithm|--->: Compare Section[primitive]......."<<endl; return; } virtual void NextPositionStartCompare() { cout<<"KMP String Algorithm|--->: Jump to the next postion[primitive]......"<<endl; return; } }; #endif  

/******************************************************************* * * DESCRIPTION:Template Pattern [Template模式] * * AUTHOR:Neesky * * DATE:2009-9-25 * *******************************************************************/ /** include files **/ #include <iostream> #include "BMStringMatchAlgorithm.h" #include "KMPStringMatchAlgorithm.h" using namespace std; int main (int argc, char *argv[]) { KMPStringMatchAlgorithm *KMP=new KMPStringMatchAlgorithm(); KMP->ExecuteMatch(); BMStringMatchAlgorithm *BM=new BMStringMatchAlgorithm(); BM->ExecuteMatch(); return (0); }  

【输出】

 

 

[GoF设计模式]Bridge模式和Template模式的C++实现_第3张图片

 

 

 

 

 

 

 

你可能感兴趣的:(Algorithm,设计模式,C++,include,Primitive,construction)