模板方法
2021-07-15
3 min read
模板方法
以下介绍几种常用的设计模式,既作复习,也是在开发实践中对于设计模式的再理解;
顺序并不按照主要教材所列,且有些内容掺杂个人理解,并非完全正确,欢迎交流探讨;
首先从模板方法开始;
目的
在开发中常会遇到这样的情况:自己写的库中,一个功能的流程是固定的,且大部分步骤具体实现也是固定的,但是其中某一些步骤的具体实现无法确定,是由使用该库的人进行开发,那么如何让别人使用该库时能够复用自己的代码呢?这就是模板方法的使用场景;
概念
模板方法:定义一个操作中稳定不变的算法骨架,将一些步骤延迟到变化的子类中,其目的是使得子类可以复用一个算法框架;
示例
在C++中,具体方法是,使用虚函数与继承实现模板方法,简单示例如下:
class Solver {
public:
Solver() = default;
virtual ~Solver() = default;
void solve()
{
preprocess();
compute();
postprocess();
}
protected:
virtual void compute()
{
// 常常变化
// ...
}
private:
void preprocess()
{
// 稳定的实现
// ...
}
void postprocess()
{
// 稳定的实现
// ...
}
// ...
};
class SolverA : public Solver {
protected:
virtual void compute() override
{
// SolverA 的计算过程
}
// ...
};
class SolverB : public Solver {
protected:
virtual void compute() override
{
// SolverB 的计算过程
}
// ...
};
class SolverC : public Solver {
protected:
virtual void compute() override
{
// SolverC 的计算过程
}
// ...
};
#include <vector>
#include <memory>
using std::vector
using std::unique_ptr;
int main()
{
unique_ptr<Solver> solA = std::make_unique<SolverA>();
unique_ptr<Solver> solB = std::make_unique<SolverB>();
// ...
vector<unique_ptr<Solver>> sol;
sol.push_back(std::move(solA));
sol.push_back(std::move(solB));
// ...
for (int i = 0; i < sol.size(); ++i) {
sol[i]->solve();
}
// ...
return 0;
}
上述代码中,Solver包含:前处理,计算,后处理三个稳定的过程,其中前处理与后处理具体实现是固定的,但是“计算”因具体方法而异,所以使用模板方法,只需实现不同的计算方法即可, 而算法流程框架、前处理与后处理代码均得到复用;
参考
本文参考 同 本博客前述<面向对象设计>一文中所参考项;
版权声明:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!