设计模式之template method模式

算法意图:

将算法骨架定义在父类当中,具体的实现放到子类当中。Template method可以不改变算法的骨架在子类中重新定义算法中的某些特定的步骤。

算法适用性:

1.       一次性将算法的不变部分封装到父类当中,将可变的部分放到子类中去实现。

2.       各子类的公共部分亚冠提取出来放到父类当中,避免代码重复,分离变化和不变的地方。

3.       通过hook来控制子类的扩展。

4.       模板方法的格式:
class TemplateMethod_Demo
{
  public:
    <返回值类型> <模板方法名>(<参数列表>); //模板方法成员函数,定义为公有的非虚成员函数,供客户调用;
  protected:
    virtual <返回值类型> <抽象操作的方法名>(<参数列表>) = 0;//抽象操作(可选),:原语操作,用纯虚函数表示,必须被重定义,定义为保护类型的,只能被模板方法本身调用;
    virtual <返回值类型> <钩子操作的方法名>(<参数列表>){};  //钩子操作(必选),:原语操作,用虚函数表示,可被重定义,提供缺省实现,定义为保护类型的,只能被模板方法本身调用;
};

 

  1// template.cpp : 定义控制台应用程序的入口点。
  2//
  3
  4#include "stdafx.h"
  5#include<iostream>
  6using namespace std;
  7
  8class AbstractClass
  9{
 10public:
 11     AbstractClass(){}
 12     virtual ~AbstractClass(){}
 13     virtual void doFirst();
 14     virtual void doAfter();
 15     // 这个函数中定义了算法的轮廓
 16     void TemplateMethod()
 17     {
 18         doFirst();
 19         PrimitiveOperation1();
 20         PrimitiveOperation2();
 21          if (b_jugle) 
 22          {
 23              doSthElse();
 24          }
 
 25         doAfter();
 26     }

 27     virtual void setHookTrue()
 28     {
 29         AbstractClass::b_jugle = true;
 30     }
;
 31
 32protected:
 33     // 纯虚函数,由派生类实现之
 34     virtual void PrimitiveOperation1() = 0;
 35     virtual void PrimitiveOperation2() = 0;
 36     virtual void  doSthElse() = 0;
 37     static bool b_jugle;
 38     
 39     
 40}
;
 41
 42bool AbstractClass::b_jugle = false;
 43
 44
 45void AbstractClass::doFirst()
 46{
 47    cout<<"do std before"<<endl;
 48}

 49
 50void AbstractClass::doAfter()
 51{
 52    cout<<"do std after"<<endl;
 53}

 54
 55// 继承自AbstractClass,实现算法
 56class ConcreateClass: public AbstractClass
 57{
 58public:
 59     ConcreateClass(){}
 60     virtual ~ConcreateClass(){}
 61
 62protected:
 63     virtual void PrimitiveOperation1()
 64     {
 65         cout << "PrimitiveOperation1 by ConcreateClass\n";
 66     }

 67     virtual void PrimitiveOperation2()
 68     {
 69         cout << "PrimitiveOperation2 by ConcreateClass\n";
 70     }

 71     virtual void doSthElse()
 72     {
 73         cout<<"so something else!\n"<<endl;
 74     }

 75}
;
 76
 77
 78// 继承自AbstractClass,实现算法
 79class ConcreateClassNew: public AbstractClass
 80{
 81public:
 82     ConcreateClassNew(){}
 83     virtual ~ConcreateClassNew(){}
 84    
 85protected:
 86     virtual void PrimitiveOperation1()
 87     {
 88         cout << "PrimitiveOperation1 by ConcreateClassNew\n";
 89     }

 90     virtual void PrimitiveOperation2()
 91     {
 92         cout << "PrimitiveOperation2 by ConcreateClassNew\n";
 93     }

 94      virtual void doSthElse()
 95     {
 96         cout<<"so something else!\n"<<endl;
 97     }

 98    
 99}
;
100
101
102int _tmain(int argc, _TCHAR* argv[])
103{
104    AbstractClass* pConcreateClass = new ConcreateClass;
105    pConcreateClass->TemplateMethod();
106    delete pConcreateClass;
107
108
109    AbstractClass* pConcreateClass2 = new ConcreateClassNew;
110    pConcreateClass2->setHookTrue();
111    pConcreateClass2->TemplateMethod();
112    delete pConcreateClass2;
113    return 0;
114}

115
116

运行结果:


template method的设计原则:
1.封装变化部分;
2.对接口编程
3. 好莱坞原则:别调用我们,在我们需要时会调用你

最后谈一下和策略模式的区别,最主要的区别是一个是使用继承而策略模式是使用组合方式。

posted on 2012-04-29 11:18 sheng 阅读(363) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

统计

常用链接

留言簿(1)

随笔档案

收藏夹

同行

搜索

最新评论

阅读排行榜

评论排行榜