使用场景
当我们想为一个对象设置多个处理方式时,可以选择策略模式。
实现代码
#include<vector>
#include<string>
#include<map>
#include<iostream>
#include <sstream>
using namespace std;
enum class outputformat {
markdown,
html
};
struct ListStrategy {
virtual void start(ostringstream& oss) {}
virtual void add_list_item(ostringstream& oss,const string& item) {}
virtual void end(ostringstream& oss) {}
};
struct TextProcessor {
ostringstream oss; //存放输出的缓冲区
unique_ptr<ListStrategy> list_strategy;
public:
void append_list(const vector<string> items) {
list_strategy->start(oss);
for (auto& item : items)
list_strategy->add_list_item(oss, item);
list_strategy->end(oss);
}
void set_output_format(const outputformat format);
};
struct HtmlListStrategy :ListStrategy {
virtual void start(ostringstream& oss) override { oss << "<ur>"; }
virtual void add_list_item(ostringstream& oss, const string& item) {
oss << " <li>" << item << " </li> ";
}
virtual void end(ostringstream& oss) { oss << "</ur>"; }
};
struct MarkdownListStrategy :ListStrategy {
virtual void add_list_item(ostringstream& oss, const string& item) {
oss << '*' << item;
}
};
void TextProcessor::set_output_format(const outputformat format) {
switch (format) {
case outputformat::markdown:
list_strategy = make_unique< MarkdownListStrategy>(MarkdownListStrategy{});
break;
case outputformat::html:
list_strategy = make_unique<HtmlListStrategy>(HtmlListStrategy{});
break;
}
}
int main()
{
TextProcessor tp{};
tp.set_output_format(outputformat::markdown);
tp.append_list({ "hi","hello","bye" });
cout << tp.oss.str()<< endl;
tp.oss.str("");
tp.set_output_format(outputformat::html);
tp.append_list({ "hi","hello","bye" });
cout << tp.oss.str() << endl;
/*
*hi*hello*bye
<ur> <li>hi </li> <li>hello </li> <li>bye </li> </ur>
*/
return 0;
}
代码中一共设置了两种输出模式,html和markdown格式输出,用户可以选择输出的策略,从而改变类的行为。
通过维护指向策略的指针实现调用策略,切换也非常简单!
总结
策略模式时通过定义通用的算法框架,然后以组件的形式提供框架内部流程的具体实现。