//---------------------------15/04/28----------------------------
//TemplateMethod 模版方法模式----类行为型模式
/*
1:意图:
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变
一个算法的结构即可重定义该算法的某些特定步骤。
2:动机:
3:适用性:
1>一次性实现算法的不变的部分,并将可变的行为留给子类来实现。
2>各子类中的公共行为应被提取出来并集中到一个公共父类中以避免代码重复。
3>控制子类的扩展。
4:结构:
AbstractClass:
TemplateMethod()
{ ... //这些...的地方是固定的,子类无权改变
PrimitiveOperation1()
...
PrimitiveOperation2()
...
}
PrimitiveOperation1
PrimitiveOperation2
|
|
|
ConcreteClass:
PrimitiveOperation1()
PrimitiveOperation2() //可重新实现的两个类
5:参与者:
1>AbstractClass:
1)定义抽象的原语操作,具体的子类将重新定义它们以实现一个算法的各步骤。
2)实现一个模板方法,定义一个算法的骨架。该模版不仅调用原语操作,也调用定义在AbstractClass
或其他对象中的操作。
2>ConcreteClass:
实现原语操作以完成算法中与特定子类相关的步骤。
6:协作:
ConcreteClass靠AbstractClass来实现算法中不变的步骤。
7:效果:
1>具体操作。
2>具体的AbstractClass的操作
3>原语操作
4>Factory Method
5>钩子操作。它提供了缺省的行为,子类可以在必要时进行扩展。
要注意什么是原语操作(pure virtual函数)什么事钩子操作(有默认实现的virtual函数)
8:实现:
1>使用C++访问控制:
原语操作可以被定义为保护成员。这保证它们只可被模版方法调用(其实也可以定义为private成员,因为
子类需要做的只是重新实现定义,而不是去使用)。原语操作必须是纯虚函数,模版方法自身可以定义为
非虚成员函数。
2>尽量减少原语操作:
定义模板方法的一个重要目的就是尽量减少一个子类具体实现该算法时必须重定义的那些原语操作的数目。
3>命名约定:
可以给必须重定义的操作加上前缀以识别他们。
9:代码示例: */
//假设MyView继承自View DoDisplay就是钩子操作,因为DoDisplay需要一个默认实现
void View::Display()
{
//设置焦点才能显示东西
SetFocus();
//子类可重定义的操作
DoDisplay();
//最后把焦点移除
ResetFocus();
}
void view::DoDisplay() {}
void MyView::DoDisplay()
{
//render the view's contents
//做一些自己想做的事,随便显示什么东西都可以
}