Head First设计模式C++实现--第八章:模板(Template)模式
来源:互联网 发布:国内旅游 知乎 编辑:程序博客网 时间:2024/06/15 21:53
模板(Template)模式
一、问题的提出
茶和咖啡的冲泡方式非常相似:
//咖啡冲泡法prepareRecipe(){boilWater();//1、把水煮沸brewCoffeeGrinds();//2、用沸水冲泡咖啡pourInCup();//3、把咖啡倒进杯子addSuarAndMilk();//4、加糖和牛奶}//茶冲泡法prepareRecipe(){boilWater();//1、把水煮沸steepTeaBag();//2、用沸水浸泡茶叶pourInCup();//3、把茶倒进杯子addLemon();//4、加柠檬}很明显上面有重复的代码,需要清理一下设计了。把相似的部分抽取出来,放进一个基类中。以上的设计中把相同的两个方法抽出来放进了基类当中,但是第二、四步是一样的算法,只是应用在不同的饮料上。于是,可以抽象的将他们换一个更合适的方法,最终的设计便是:prepareRecipe(){boilWater();//1、把水煮沸brew();//2、用沸水冲泡pourInCup();//3、把饮料倒进杯子addCondiments();//4、加调料}
二、认识模板方法
头文件:
#ifndef TEMPLATE__H#define TEMPLATE__H#include <iostream>using namespace std;//咖啡因饮料超类class CaffeineBeverage{public:virtual void prepareRecipe() = 0;//这是模板方法,因为:它是一个算法的模板。(在这个例子中,这个算法是用来制作饮料的)//在这个模板中,算法内的每一个步骤都被一个方法代表了,某些方法是由这个超类处理的,某些方法由子类处理,需要子类处理的方法被声明为抽象void boilWater();virtual void brew() = 0;void pourInCup();virtual void addCondiments() = 0;};//茶class Tea : public CaffeineBeverage{public:void brew();void addCondiments();};//咖啡class Coffee : public CaffeineBeverage{public:void brew();void addCondiments();};#endif
cpp文件#include "Template.h"void CaffeineBeverage::boilWater(){cout<<"Boiling water"<<endl;}void CaffeineBeverage::pourInCup(){cout<<"Pouring into cup"<<endl;}//模板方法void CaffeineBeverage::prepareRecipe(){boilWater();brew();pourInCup();addCondiments();}void Tea::brew(){cout<<"Steeping the tea"<<endl;}void Tea::addCondiments(){cout<<"Adding Lemon"<<endl;}void Coffee::brew(){cout<<"Dripping Coffee through filter"<<endl;}void Coffee::addCondiments(){cout<<"Adding Sugar and Milk"<<endl;}
定义模板方法模式:模板方法模式在一个方法中定义一个算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些实现步骤。
这个模式就是用来创建一个算法的模板。什么是模板?模板就是一个方法。更具体的说,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,有子类负责。这可以确保算法的结构保持不变,同时由子类提供部分实现。2.1添加钩子
头文件://咖啡因饮料超类,具有钩子class CaffeineBeverageWithHook{public:virtual void prepareRecipe() = 0;//这是模板方法,因为:它是一个算法的模板。(在这个例子中,这个算法是用来制作饮料的)//在这个模板中,算法内的每一个步骤都被一个方法代表了,某些方法是由这个超类处理的,某些方法由子类处理,需要子类处理的方法被声明为抽象void boilWater();virtual void brew() = 0;void pourInCup();virtual void addCondiments() = 0;//添加钩子函数,由顾客决定是否需要添加调料bool customerWantsCondiments();};class TeaWithHook : public CaffeineBeverageWithHook{public:void prepareRecipe();void brew();void addCondiments();bool customerWantsCondiments();};//咖啡class CoffeeWithHook : public CaffeineBeverageWithHook{public:void prepareRecipe();void brew();void addCondiments();bool customerWantsCondiments();};
cpp文件void CaffeineBeverageWithHook::boilWater(){cout<<"Boiling water"<<endl;}void CaffeineBeverageWithHook::pourInCup(){cout<<"Pouring into cup"<<endl;}bool CaffeineBeverageWithHook::customerWantsCondiments(){return true;}//模板方法void CaffeineBeverageWithHook::prepareRecipe(){boilWater();brew();pourInCup();if(customerWantsCondiments())addCondiments();}void TeaWithHook::brew(){cout<<"Steeping the tea"<<endl;}void TeaWithHook::addCondiments(){cout<<"Adding Lemon"<<endl;}//钩子,子类覆盖这个钩子。在此默认返回truebool TeaWithHook::customerWantsCondiments(){char t;cout<<"Would you like Lemon with your tea?(y/n)"<<endl;cin>>t;if(t == 'y')return true;return false;}void TeaWithHook::prepareRecipe(){boilWater();brew();pourInCup();if(customerWantsCondiments())addCondiments();}void CoffeeWithHook::brew(){cout<<"Dripping Coffee through filter"<<endl;}void CoffeeWithHook::addCondiments(){cout<<"Adding Sugar and Milk"<<endl;}//钩子,子类覆盖这个钩子。在此默认返回truebool CoffeeWithHook::customerWantsCondiments(){char t;cout<<"Would you like milk and sugar with your coffee?(y/n)"<<endl;cin>>t;if(t == 'y')return true;return false;}void CoffeeWithHook::prepareRecipe(){boilWater();brew();pourInCup();if(customerWantsCondiments())addCondiments();}
测试代码:#include "Template.h"#include <iostream>using namespace std;int main(){TeaWithHook* teaHook = new TeaWithHook();CoffeeWithHook* coffeeHook = new CoffeeWithHook();cout<<"Making tea..."<<endl;teaHook->prepareRecipe();cout<<endl<<"Making coffee..."<<endl;coffeeHook->prepareRecipe();delete teaHook;delete coffeeHook;getchar();getchar();}好莱坞原则:别调用我们,我们会调用你。当我们设计模板方法模式时,我们告诉子类,“不要调用我们,我们会调用你”。
三、模板和策略模式的比较
模板方法模式:1、定义一个算法大纲,由其子类定义其中某些步骤的内容。这么一来,在算法中的个别步骤可以有不同的实现细节,但是算法的结构依然维持不变。2、对算法由更多的控制权,而且不会重复代码。事实上,除了极少的一部分之外,算法的每一个部分都是相同的,所以类的效率高一些。会重复使用到的代码,都被放进了超类当中,好让所有子类继承。策略模式:1、定义一个算法家族,并让这些算法可以互换。正因为每一个散发都被封装起来了,所以客户可以轻易地使用不同的算法。2、使用对象组合,比较有弹性,客户能在运行时改变算法,而客户所要做的,只是改用不同的策略对象。
0 0
- Head First设计模式C++实现--第八章:模板(Template)模式
- Template Method-模板方法模式《Head First 设计模式》
- First head 设计模式学习c++实现------模板方法模式(Template method pattern)
- Head First设计模式C++实现--第九章:迭代器(Template)模式
- Head First设计模式-模板方法模式
- 《Head First 设计模式》模板方法模式
- Head First 设计模式 (八) 模版方法模式(Template method pattern) C++实现
- Head First 设计模式
- Head-first设计模式
- head first 设计模式
- head first 设计模式
- Head First 设计模式
- 《Head First 设计模式》
- Head First设计模式
- Head First《设计模式》
- 《Head First设计模式》
- Head First设计模式
- C++设计模式实现--模板(Template)模式
- 刚接触开发板之使用vmware和预先做好的ubuntu
- POJ 2031 Building a Space Station
- HDU 2897 邂逅明下 (经典博弈变形)
- Apache/Nginx 日志实时监控可视化工具
- NOJ1092圆柱体的表面积——水题
- Head First设计模式C++实现--第八章:模板(Template)模式
- [LeetCode] Reverse Linked List II
- 调试WebService接口的小工具-storm
- 远程SHELL执行框架 sshxcute
- 解决“飞鸽传书”无法显示局域网用户的方法
- OCP 1Z0 053 77
- 纠结了好几个小时关于在标识符前缺少;的问题
- CSS继承性
- MyConnection Server 是一个带宽测试软件