学以致用C++设计模式 “模板方法模式”

时间:2022-07-23
本文章向大家介绍学以致用C++设计模式 “模板方法模式”,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

新品上市

我那位朋友,果然是有雄心壮志的人,这不,最近要开拓汉堡业务,想要有一条流水线生产,又不想太死板,正发愁呢。 正好这天我又到他的店里吃饭,看他眉头紧锁,我便给丫出了个主意,顺便免单。 主意是这样的: 你安排一条流水,把固定步骤定下来,比方说烤面包、烤肉、加奶油、上生菜、面包夹肉。 然后具体用料由具体工作人员来确定,这样不就结了,一条线下来,总体工作步骤一致,但是可以生产各种你要的汉堡。

我们来看一下这个方法,它包含了几个什么因素?首先是汉堡(目的产品),一条主流水、然后是生产人员,生产出各种汉堡。

我们将这个流程画出一个类图来看:

那这个流程不就相当的清楚且简单了吗

代码实现

#include<iostream>

using namespace std;

class abstracthumber {
public:
	virtual void bread() = 0;
	virtual void barbecue() = 0;
	virtual void cream() = 0;
	virtual void lettuce() = 0;

	void run()	//将共同的核心算法流程提炼到抽象类
	{
		this->bread();
		this->barbecue();
		this->cream();
		this->lettuce();
	}
};

//将细节延迟到子类
//这两步便是模板方法模式的精髓
class chicken :public abstracthumber {
public:
	void bread() { cout << "鸡腿堡的面包" << endl; }
	void barbecue() { cout << "鸡腿堡的鸡腿" << endl; }
	void cream() { cout << "鸡腿堡的奶油" << endl; }
	void lettuce() { cout << "鸡腿堡的生菜" << endl; }
};

class beef :public abstracthumber {
public:
	void bread() { cout << "牛肉堡的面包" << endl; }
	void barbecue() { cout << "牛肉堡的鸡腿" << endl; }
	void cream() { cout << "牛肉堡的奶油" << endl; }
	void lettuce() { cout << "牛肉堡的生菜" << endl; }
};


int main()
{
	abstracthumber* a = new chicken();
	abstracthumber* b = new beef();

	a->run();
	b->run();
}

我的思考

这方法挺好,将核心算法和细节实现解耦合,不过也是那个拓展的问题还是会存在。

模板方法模式定义

定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

所以,如果要改算法,那就重构吧。

用武之地

模板方法的有点

  • 封装不变部分,拓展可变部分(把认为是不变部分的算法封装到父类实现,而可变部分可以通过继承来继续拓展。如果要在来个新产品,虾堡,知道怎么做吧,可以自己做一下)
  • 提取公共部分代码,便于维护。想想看,那个run要是放到子类,那要修改会有几倍工作量?
  • 行为由父类控制,子类实现。

模板方法的缺点

  • 子类对父类产生了影响,这会加大代码的理解难度,对新手不太友好。

使用场景

  • 多个子类有共同的方法,并且逻辑基本相同。
  • 重要、复杂的算法,可以把核心算法设计为模板方法,周边细节由各个子类实现。
  • 重构时,模板方法模式是一个常见的模式。

模板方法模式的拓展

可以自己去试试写一个,造车的模板。

今天就到这里,下一篇会是什么嘞?对,和模板方法模式相似度挺高的“建造者模式”!