设计模式5 行为模式
行为模式,目录: 模式方法模式 命令模式 策略模式观察者模式
模板方法模式:冲咖啡,冲茶水
chunli@linux:~$ cat main.cpp
#include <iostream>
using namespace std;
//抽象的制作饮料方法
class MakeDrink
{
public:
//1 把水煮开
void boil() {
cout << "把水煮开" << endl;
}
//2 冲某物
virtual void brew() = 0;
//3 从大杯倒入小杯
void putInCup()
{
cout << "把冲泡好的饮料 从大杯倒入小杯" << endl;
}
//4 加一些酌料
virtual void addThings() = 0;
//钩子函数, hook
virtual bool CustomWantAddThings() {
return true;
}
//业务的逻辑的统一模板
void make() {
boil();
brew(); //子类
putInCup();
if (CustomWantAddThings() == true) {
addThings(); //子类的多态
}
}
};
//制作咖啡
class MakeCoffee :public MakeDrink
{
public:
MakeCoffee(bool isAdd)
{
this->isAdd = isAdd;
}
//2 冲某物
virtual void brew()
{
cout << "冲泡咖啡豆" << endl;
}
//4 加一些酌料
virtual void addThings() {
cout << "添加糖和牛奶" << endl;
}
virtual bool CustomWantAddThings() {
return isAdd;
}
private:
bool isAdd;
};
//冲泡茶叶
class MakeTea :public MakeDrink
{
public:
MakeTea(bool isAdd)
{
this->isAdd = isAdd;
}
//2 冲某物
virtual void brew() {
cout << "冲泡 茶叶" << endl;
}
//4 加一些酌料
virtual void addThings() {
cout << "添加 柠檬 或者 菊花" << endl;
}
virtual bool CustomWantAddThings() {
return isAdd;
}
private:
bool isAdd;
};
int main(void)
{
MakeDrink *makeCoffee = new MakeCoffee(true);
makeCoffee->make();
cout << " ------ " << endl;
MakeDrink *makeTea = new MakeTea(false);
makeTea->make();
return 0;
}
chunli@linux:~$ g++ main.cpp && ./a.out
把水煮开
冲泡咖啡豆
把冲泡好的饮料 从大杯倒入小杯
添加糖和牛奶
------
把水煮开
冲泡 茶叶
把冲泡好的饮料 从大杯倒入小杯
chunli@linux:~$模板方法模式中的角色和职责
AbstractClass(抽象类):在抽象类中定义了一系列基本操作
(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一
个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同
时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法
的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽
象类的子类中实现的基本方法,还可以调用其他对象中的方法。
ConcreteClass(具体子类): 它是抽象类的子类,用于实现在父类中声
明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现
的具体基本操作。
模板方法的优缺点
优点:
(1) 在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在
子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
(2) 模板方法模式是一种代码复用技术,它在类库设计中尤为重要,它提取
了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行
为,它鼓励我们恰当使用继承来实现代码复用。
(3) 可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特
定步骤是否需要执行。
(4) 在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可
以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则
和开闭原则。
缺点:
需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本
方法太多,将会导致类的个数增加,系统更加庞大,设计也更加抽象。
适用场景
(1)具有统一的操作步骤或操作过程;
(2) 具有不同的操作细节;
(3) 存在多个具有同样操作步骤的应用场景,但某些具体的操作细节却各
不相同;
在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样
可以把各个具体的子类和操作步骤解耦合。
本文出自 “魂斗罗” 博客,转载请与作者联系!
原文:http://990487026.blog.51cto.com/10133282/1877871