定义

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法(Template Method)使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
 
结构

 

 


 

理解
1.       AbstractClass是一个抽象的基类:
定义一系列的抽象原语操作(Primitive Operation)。具体的子类(Concrete Class)将重新实现这些操作。原语操作实际上就是虚方法。
基类定义和实现了模板方法(Template Method)。模板方法调用基类定义的原语操作或其他方法完成一个算法的骨架。模板方法是非虚方法,子类不需要重新实现模板方法。
2.       ConcreteClass是具体的子类,实现抽象基类的原语操作。
3.       模板方法模式使得子类可以不改变一个算法的结构,就可重定义该算法的某些特定步骤。这些都是利用了C++的继承和多态特性。
 
要点
1.       模版方法模式在软件设计和代码复用中使用非常广泛,利用面向对象的多态特性,以至于很多时候你用到了模板方法,但你却没有发现。
2.       基类的模版方法调用的方法可以是:具体方法、虚方法、纯虚方法。由于这些方法仅供TemplateMethod方法调用,因此最好是protected的。
具体方法:不需要子类重新实现。这是模板方法调用中中不可变的部分,可变发部分留给子类扩展实现。
纯虚方法:必须要求子类重新实现。
虚方法:基类提供了默认实现(一般是空方法),子类可根据需求来选择是否重新实现。这类方法通常叫做钩子方法Hook Method),钩子方法来源于Windows的消息处理机制,命名一般约定是Do开头的。
3.       模板方法模式,要尽量减少抽象原语操作的数量,即尽量减少纯虚方法和钩子方法的数量,基类尽量实现更多的具体方法。
4.       模板方法是非虚成员方法,子类不需要重新实现模板方法。
5.       模板方法模式,其实是反向控制结构。基类的模板方法调用子类延迟实现的钩子方法。

应用
这里用一个线程类的实现来解释模板方法设计模式的应用。
线程调用的过程是:创建线程、调用线程方法。这个逻辑是不变的,线程调用的过程就是模板方法。
线程执行的工作内容是变化的,每个继承的线程类的工作内容是不同的。线程的工作方法就是抽象原语操作,基类通过扩展这个钩子方法实现不同的需求。
 
源码
#include <iostream>
using namespace std;
 
//这是AbstractClass
class CBaseThread
{
public:
    CBaseThread()
    {
        cout << "CBaseThread::CBaseThread()" << endl;
    }
    virtual ~CBaseThread()
    {
        cout << "CBaseThread::~CBaseThread()" << endl;
    }
 
    //启动线程的入口
    //这是模板方法TemplateMethod(),是非虚成员方法
    int Start()
    {
        cout << "CBaseThread::Start()" << endl;
        //简单化,实际是要调用pthread_create()
        CBaseThread::Run(this);
        return 0;
    }
 
protected:
 
    //线程调用工作方法的入口
    //这是基类实现的具体方法,不需要子类重新实现。
    static void* Run(void* pParam)
    {
        cout << "CBaseThread::Run()" << endl;
        CBaseThread* pThread = static_cast<CBaseThread*>(pParam);
        pThread->DoWork();
        return NULL;
    }
 
    //线程工作方法
    //这是一个抽象原语操作。钩子方法由子类扩展。
    virtual int DoWork()
    {
        cout << "CBaseThread::DoWork()" << endl;
        return 0;
    }
};
 
//这是ConcreteClass
class CMyThread : public CBaseThread
{
public:
    CMyThread()
    {
        cout << "CMyThread::CMyThread()" << endl;
    }
    virtual ~CMyThread()
    {
        cout << "CMyThread::~CMyThread()" << endl;
    }
 
protected:
    //扩展钩子方法
    virtual int DoWork()
    {
        cout << "CMyThread::DoWork()" << endl;
        return 0;
    }
};
 
int main()
{
    //直接调用模板方法实现基类对子类的控制
    CBaseThread* pThread = new CMyThread();
    pThread->Start();
    delete pThread;
 
    system("pause");
    return 0;
}
 
输出:
CBaseThread::CBaseThread()
CMyThread::CMyThread()
CBaseThread::Start()
CBaseThread::Run()
CMyThread::DoWork()
CMyThread::~CMyThread()
CBaseThread::~CBaseThread()

 


转载本站文章请注明,转载自:神秘果

本文链接: http://www.shenmiguo.com/archives/2009/279_design-patterns-template-method.html

5 Responses to “C++设计模式-模板方法”

  1. Holy szhiint, this is so cool thank you.

  2. JlehTo bqomofaptkee

  3. j6MIKH , [url=http://hmafjhbnhcxq.com/]hmafjhbnhcxq[/url], [link=http://pamscgfyiwik.com/]pamscgfyiwik[/link], http://vhnqryywwghi.com/

  4. MSEkmo rgnmpriqfohw

  5. zvV9My , [url=http://nekoemqfymdi.com/]nekoemqfymdi[/url], [link=http://quskpxkphqsy.com/]quskpxkphqsy[/link], http://ewhleleemsbv.com/

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <font color="" face="" size=""> <span style="">

*