一道题采用两种设计模式:对比策略模式和模版方法
摘要
《C++ Primer》习题14.38和14.39分别采用策略模式、模版方法解决问题。
问题
《C++ Primer 5th》习题 14.38 : 编写一个类令其检查某个给定的 string 对象的长度是否与一个阀值相等。使用该对象编写程序,统计并报告输入的文件中长度为 1 的单词有多少个、长度为 2 的单词有多少个、......、长度为 10 的单词有多少个。
《C++ Primer 5th》习题 14.39 : 修改上一题的程序令其报告长度在 1 至 9 之间的单词有多少个、长度在 10 以上的单词又有多少个。
解法一 模版方法 Template Method
UML 类图如下:
Solution 代码如下:
template <typename T> struct Solution { Solution(int n) :val(n) {} virtual ~Solution() {} virtual void operator() (const T& e) = 0; unsigned int val; int times = 0; };
EqualSolution 代码如下:
template <typename T> struct EqualSolution : public Solution<T>{ Solution::Solution; virtual void operator() (const T& e) override { if (e.size() == this->val) this->times++; } };
GreaterSolution 代码如下:
template <typename T> struct GreaterSolution : public Solution<T> { Solution::Solution; virtual void operator() (const T& e) override { if (e.size() > this->val) this->times++; } };
LesserSolution 代码如下:
template <typename T> struct LesserSolution : public Solution<T> { Solution::Solution; virtual void operator() (const T& e) override { if (e.size() < this->val) this->times++; } };
客户端调用代码如下:
int main() { vector<string> v{ "a", "b", "abc", "abcd", "abcde", "abcdef" }; Solution<string>* es = new EqualSolution<string>(1); Solution<string>* ls = new LesserSolution<string>(5); Solution<string>* gs = new GreaterSolution<string>(5); for (auto &e : v) { es->operator()(e); ls->operator()(e); gs->operator()(e); } cout << "长度等于 1 的有几个: " << es->times << endl; cout << "长度小于 5 的有几个: " << ls->times << endl; cout << "长度大于 5 的有几个: " << gs->times << endl; return 0; }
解法二 策略方法 + 工厂方法
UML类图如下:
CompareStrategy 代码如下:
struct CompareStrategy { virtual void operator() (const string& s, const unsigned int val, unsigned int& times) = 0; virtual ~CompareStrategy() {}; };
EqualStrategy 代码如下:
struct EqualStrategy : public CompareStrategy { virtual void operator() (const string& s, const unsigned int val, unsigned int& times) { if (s.size() == val) times++; } };
GreaterStrategy 代码如下:
struct GreaterStrategy : public CompareStrategy { virtual void operator() (const string& s, const unsigned int val, unsigned int& times) { if (s.size() > val) times++; } };
LesserStrategy 代码如下:
struct LesserStrategy : public CompareStrategy { virtual void operator() (const string& s, const unsigned int val, unsigned int& times) { if (s.size() < val) times++; } };
Context 代码如下:
struct Context { CompareStrategy *strategy; unsigned int times = 0; unsigned int val = 0; void operator() (const string& s) { strategy->operator() (s, val, times); } Context(char type, int v) : val(v) { switch (type) // 简单工厂模式 { case 'e': // equal strategy = new EqualStrategy(); break; case 'g': // greater strategy = new GreaterStrategy(); break; case 'l': // lesser strategy = new LesserStrategy(); break; default: cout << "不存在该方法" << endl; exit(-1); break; } } };
客户端调用代码如下:
int main() { vector<string> v{ "1", "12", "123", "1234" }; Context c1('e', 3); Context c2('g', 3); Context c3('l', 3); for (auto &e : v) { c1(e); c2(e); c3(e); } cout << c1.times << endl; cout << c2.times << endl; cout << c3.times << endl; return 0; }
总结
两种模式下,耦合度都不高,但是采用策略模式更合乎人类的思维。
所以这道题,策略模式更适用。
智慧在街市上呼喊,在宽阔处发声。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)