C++的策略模式简单实现
一般的策略模式(运行时多态)
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <sstream>
using namespace std;
class ListStrategy
{
public:
ListStrategy() = default;
ListStrategy(const ListStrategy& tmp) = delete;
ListStrategy& operator=(const ListStrategy& tmp) = delete;
virtual ~ListStrategy() = default;
virtual void add_list_item(ostringstream& oss, const string& item) = 0;
virtual void start(ostringstream& oss) = 0;
virtual void end(ostringstream& oss) = 0;
};
class MarkdownListStrategy : public ListStrategy
{
public:
void add_list_item(ostringstream& oss, const string& item) override
{
oss << " * " << item << endl;
}
void start(ostringstream& oss) override
{
}
void end(ostringstream& oss) override
{
}
};
class HtmlListStatrgy : public ListStrategy
{
public:
void add_list_item(ostringstream& oss, const string& item) override
{
oss << "<li>" << item << "</li>" << endl;
}
void start(ostringstream& oss) override
{
oss << "<ul>" << endl;
}
void end(ostringstream& oss) override
{
oss << "</ul>" << endl;
}
};
class TextProcess
{
public:
TextProcess(unique_ptr<ListStrategy> list_stategy): list_strategy_(std::move(list_stategy))
{
}
void clear()
{
oss_.str("");
oss_.clear();
}
void appendList(const vector<string>& items)
{
list_strategy_->start(oss_);
for (auto& it : items)
list_strategy_->add_list_item(oss_, it);
list_strategy_->end(oss_);
}
string str() const
{
return oss_.str();
}
private:
ostringstream oss_;
unique_ptr<ListStrategy> list_strategy_;
};
int main()
{
TextProcess tp1(make_unique<MarkdownListStrategy>());
tp1.appendList({"test", "xiaoyan", "xiaolong"});
cout << tp1.str() << endl;
TextProcess tp2(make_unique<HtmlListStatrgy>());
tp2.appendList({ "test", "xiaoyan", "xiaolong" });
cout << tp2.str() << endl;
getchar();
return 0;
}
优化后的策略模式(通过模板编程实现编译时多态)
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <sstream>
using namespace std;
class MarkdownListStrategy
{
public:
void add_list_item(ostringstream& oss, const string& item)
{
oss << " * " << item << endl;
}
void start(ostringstream& oss)
{
}
void end(ostringstream& oss)
{
}
};
class HtmlListStatrgy
{
public:
void add_list_item(ostringstream& oss, const string& item)
{
oss << "<li>" << item << "</li>" << endl;
}
void start(ostringstream& oss)
{
oss << "<ul>" << endl;
}
void end(ostringstream& oss)
{
oss << "</ul>" << endl;
}
};
template <typename policy>
class TextProcess
{
public:
TextProcess(unique_ptr<policy> list_stategy): list_strategy_(std::move(list_stategy))
{
}
void clear()
{
oss_.str("");
oss_.clear();
}
void appendList(const vector<string>& items)
{
list_strategy_->start(oss_);
for (auto& it : items)
list_strategy_->add_list_item(oss_, it);
list_strategy_->end(oss_);
}
string str() const
{
return oss_.str();
}
private:
ostringstream oss_;
unique_ptr<policy> list_strategy_;
};
int main()
{
TextProcess<MarkdownListStrategy> tp1(make_unique<MarkdownListStrategy>());
tp1.appendList({"test", "xiaoyan", "xiaolong"});
cout << tp1.str() << endl;
TextProcess<HtmlListStatrgy> tp2(make_unique<HtmlListStatrgy>());
tp2.appendList({ "test", "xiaoyan", "xiaolong" });
cout << tp2.str() << endl;
getchar();
return 0;
}
通过继承,并优化空基类
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <sstream>
using namespace std;
class MarkdownListStrategy
{
public:
void add_list_item(ostringstream& oss, const string& item)
{
oss << " * " << item << endl;
}
void start(ostringstream& oss)
{
}
void end(ostringstream& oss)
{
}
};
class HtmlListStatrgy
{
public:
void add_list_item(ostringstream& oss, const string& item)
{
oss << "<li>" << item << "</li>" << endl;
}
void start(ostringstream& oss)
{
oss << "<ul>" << endl;
}
void end(ostringstream& oss)
{
oss << "</ul>" << endl;
}
};
template <typename policy>
class TextProcess : private policy
{
public:
void clear()
{
oss_.str("");
oss_.clear();
}
void appendList(const vector<string>& items)
{
policy::start(oss_);
for (auto& it : items)
policy::add_list_item(oss_, it);
policy::end(oss_);
}
string str() const
{
return oss_.str();
}
private:
ostringstream oss_;
};
int main()
{
TextProcess<MarkdownListStrategy> tp1;
tp1.appendList({"test", "xiaoyan", "xiaolong"});
cout << tp1.str() << endl;
TextProcess<HtmlListStatrgy> tp2;
tp2.appendList({ "test", "xiaoyan", "xiaolong" });
cout << tp2.str() << endl;
getchar();
return 0;
}