设计模式总结(二)
原型模式:
原型模式,DP书上的定义为:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
主要用于获取深拷贝的对象。
例子:参考自:http://blog.csdn.net/wuzhekai1985/article/details/6667020
//父类 class Resume { protected: char *name; public: Resume() {} virtual ~Resume() {} virtual Resume* Clone() { return NULL; } virtual void Set(char *n) {} virtual void Show() {} }; class ResumeA : public Resume { public: ResumeA(const char *str); //构造函数 ResumeA(const ResumeA &r); //拷贝构造函数 ~ResumeA(); //析构函数 ResumeA* Clone(); //克隆,关键所在 void Show(); //显示内容 }; ResumeA::ResumeA(const char *str) { if(str == NULL) { name = new char[1]; name[0] = '\0'; } else { name = new char[strlen(str)+1]; strcpy(name, str); } } ResumeA::~ResumeA() { delete [] name;} ResumeA::ResumeA(const ResumeA &r) { name = new char[strlen(r.name)+1]; strcpy(name, r.name); } ResumeA* ResumeA::Clone() { return new ResumeA(*this); } void ResumeA::Show() { cout<<"ResumeA name : "<<name<<endl; } 这里只给出了ResumeA的实现,ResumeB的实现类似。使用的方式如下: int main() { Resume *r1 = new ResumeA("A"); Resume *r2 = new ResumeB("B"); Resume *r3 = r1->Clone(); Resume *r4 = r2->Clone(); r1->Show(); r2->Show(); //删除r1,r2 delete r1; delete r2; r1 = r2 = NULL; //深拷贝所以对r3,r4无影响 r3->Show(); r4->Show(); delete r3; delete r4; r3 = r4 = NULL; }
模板方法模型:
模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类,而不是接口。
基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
(1) 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。在C#语言里一个抽象方法以abstract关键字标识。
(2) 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
(3) 钩子方法:一个钩子方法由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。
在模板方法模式中,钩子方法有两类:第一类钩子方法可以与一些具体步骤“挂钩”,以实现在不同条件下执行模板方法中的不同步骤,这类钩子方法的返回类型通常是bool类型的,这类方法名一般为IsXXX(),用于对某个条件进行判断,如果条件满足则执行某一步骤,否则将不执行,如下代码片段所示:
例:转自:http://blog.csdn.net/lovelion/article/details/8299794
- //模板方法
- public void TemplateMethod()
- {
- Open();
- Display();
- //通过钩子方法来确定某步骤是否执行
- if (IsPrint())
- {
- Print();
- }
- }
- //钩子方法
- public bool IsPrint()
- {
- return true;
- }
建造者模式
建造者模式的定义将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示(DP)。
例:http://blog.csdn.net/wuzhekai1985/article/details/6667467
- class Builder
- {
- public:
- virtual void BuildHead() {}
- virtual void BuildBody() {}
- virtual void BuildLeftArm(){}
- virtual void BuildRightArm() {}
- virtual void BuildLeftLeg() {}
- virtual void BuildRightLeg() {}
- };
- //构造瘦人
- class ThinBuilder : public Builder
- {
- public:
- void BuildHead() { cout<<"build thin body"<<endl; }
- void BuildBody() { cout<<"build thin head"<<endl; }
- void BuildLeftArm() { cout<<"build thin leftarm"<<endl; }
- void BuildRightArm() { cout<<"build thin rightarm"<<endl; }
- void BuildLeftLeg() { cout<<"build thin leftleg"<<endl; }
- void BuildRightLeg() { cout<<"build thin rightleg"<<endl; }
- };
- //构造胖人
- class FatBuilder : public Builder
- {
- public:
- void BuildHead() { cout<<"build fat body"<<endl; }
- void BuildBody() { cout<<"build fat head"<<endl; }
- void BuildLeftArm() { cout<<"build fat leftarm"<<endl; }
- void BuildRightArm() { cout<<"build fat rightarm"<<endl; }
- void BuildLeftLeg() { cout<<"build fat leftleg"<<endl; }
- void BuildRightLeg() { cout<<"build fat rightleg"<<endl; }
- };
- //构造的指挥官
- class Director
- {
- private:
- Builder *m_pBuilder;
- public:
- Director(Builder *builder) { m_pBuilder = builder; }
- void Create(){
- m_pBuilder->BuildHead();
- m_pBuilder->BuildBody();
- m_pBuilder->BuildLeftArm();
- m_pBuilder->BuildRightArm();
- m_pBuilder->BuildLeftLeg();
- m_pBuilder->BuildRightLeg();
- }
- };
客户的使用方式:
- int main()
- {
- FatBuilder thin;
- Director director(&thin);
- director.Create();
- return 0;
- }
建造者模式和模板方法模式,都是给出了大概的算法框架,模板方法把不变行为搬移到父类(超类),去除了类中的重复代码来体现它的优势,而建造者模式则是由建造者类来保存建造过程。
如果算法逻辑复杂,且需要多个建造方法,建造者模式将一个复杂对象的构建与它的表示分离,则十分方便,而如果固定方法较少,模板方法也未尝不可。