C++设计模式——模板方法模式

设计模式 - 模版方法
场景
小张的团队最近接受一个需求,实现实现一家咖啡店的冲泡咖啡和茶的冲泡自动化。之前这家咖啡店都是由咖啡师傅手动进行调制咖啡和茶。现在咖啡店需要引入自动化的点单和调制饮料的系统,小张负责实现调制饮料的功能。

咖啡师傅手工冲泡咖啡和茶的流程:

冲泡咖啡:

把水煮沸
用沸水冲泡咖啡
把咖啡倒入杯子
加糖和牛奶
冲泡茶:

把水煮沸
用沸水冲泡茶叶
把茶倒入杯子
加柠檬
小张先简单的想了一下, 如果直接实现程序,那么新建调制咖啡和调制茶的对象,在每个对象里面实现上述步骤。这样想了之后小张本想直接实现,但是由于信心不足,找老王帮他code review一下思路。 老王说,小张啊,你这实现也可以,不过不够优雅啊,你在仔细看一下上述步骤,有没有发现重复或者共性。

小张听了老王的话,觉得自己的设计应该太粗暴了,按照老王的引导,小张仔细看了上述步骤,发现上述步骤,1和4 是很相像的。4(加糖和牛奶/加柠檬)步骤相当于增加调料本质是相同的。那么他应该封装一下冲泡咖啡/茶的步骤算法。

找出共性进行封装,减少重复代码,使系统达到维护和扩展成本很低的状态。

老王夸奖到,很不错嘛,小张你已经慢慢的了解了面向对象(OOP)及使用设计模式的原因。你可以了解一下模版方法。

模版方法
模版方法实现冲泡咖啡
小张去了解了一下模版方法。针对上述冲泡步骤进行了思考。

应该有一个抽象的对象来描述冲泡饮料这一行为,并且抽象的类实现了具体冲泡对象的共性步骤也就是1.把水煮沸和3.把饮料倒入杯子。有两个具体的子类来具体实现冲泡茶和咖啡。
并且有些客户不需要加调料,那么需要对最后一步进行判断,是否添加调料。

我们来看一下小张的类图:

模版方法:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模版方法使得子类可以在不改变算法结构的情况下,重新定义算法中某些步骤

#define  _CRT_SECURE_NO_WARNINGS 
#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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值