首先我们先来抽象一下。
模板方法模式:属于行为模式
意图:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod是的子类可以不改变算法结构即可定义该算法的某些步骤
我们可以想象一些现实例子,去淘宝买衣服往往步骤是比较稳定和明确的,我们无非需要 登录淘宝->选择喜欢的产品->下单。这样三个步骤,但是你很快就会发现,尽管登录和下单是两个稳定的步骤,但是,选择商品这一环节可以是时刻变化的。
比较不好的实现方式是:
class Base { public: bool login(); void buy(Good *good); } class App { public: Good *choiceBest(); } int main() { Base a; App b; if(a.login()) { a.buy(b.choiceBest()); } }
上面代码,必须等到运行时才能确定步骤,并且由用户来确定。这是没有必要的,因为我们的假定是,这个步骤是恒定不变的,所以,应该采取一种可以更为优秀的做法,那就是模板方法,我们需要一个方法,用来执行这个固定的步骤,也就是一个确定的算法骨架。
所以,我们运用模板方法模式,我改成这样一种形式:
class Base { public : bool login(); virtual Good *choiceBest()=0; void buy(Good *good); void templateRun() //重点的模板方法就是我 { if(login()) { buy(choiceBest); } } }
这个是一开始确定的抽象基类,于是,当我们要使用这样一种方法,我们只需要:
class App:Public Base { public: Good *choiceBest() { //具体实现 } }
对抽象的方法进行具体实现。
运行时:
int main() { Base * a = new App(); a->templateRun(); delete a; }
我们只需要关注变化的具体实现。好在回头看看模板方法的定义,怎么样,大概就是这样一种结构图:
这是书上的结构图,也就是说,一个基本的抽象类,用于定义确定的步骤,和保护一个模板方法,我们只需要定义我们具体的类实现一些后期的步骤即可。
这里面我们会看到两种函数方法,一种是具体的函数方法 ,还有一种是抽象的函数方法 ,在c++语法里面我们,通过virtual关键字,并且在声明后面加上=0语法来保证后代一定要实现,具体的讲就是,抽象方法要求后代必须去写它的具体实现。当然事实上,还有一种钩子方法, 如果我们不要求后代必须实现,我们事先有一套缺省的执行实现,那么我们可以把=0去掉,确定为一个钩子方法。