-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathdynamic_strategy.cpp
More file actions
103 lines (88 loc) · 2.38 KB
/
dynamic_strategy.cpp
File metadata and controls
103 lines (88 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
/**
* This Example shows how the strategy pattern can be used to dynamically select
* the text processor (markdown or html) for list creation.
*
* HTLM:
* <ul>
* <li> Foo
* <li> Bar
* <ul>
*
* Markdown:
* * Foo
* * Bar
*/
enum class OutputFormat { Markdown, Html };
struct ListStrategy {
virtual ~ListStrategy() = default;
// Common Behavior
virtual void add_list_item(ostringstream &, const string &){};
virtual void start(ostringstream &){};
virtual void end(ostringstream &){};
};
struct MarkdownListStrategy : ListStrategy {
// specific behavior
void add_list_item(ostringstream &oss, const string &item) override {
oss << " * " << item << endl;
}
// NOTE: dynamic polymorphism allows us to not implement the start() and end()
// methods.
};
struct HtmlListStrategy : ListStrategy {
// specific behavior
void start(ostringstream &oss) override { oss << "<ul>" << endl; }
void end(ostringstream &oss) override { oss << "</ul>" << endl; }
void add_list_item(ostringstream &oss, const string &item) override {
oss << "<li>" << item << "</li>" << endl;
}
};
struct TextProcessor {
void clear() {
oss.str("");
oss.clear();
}
void append_list(const vector<string> &items) {
// User calls the general interface, independent of the actual
// implementation.
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) {
switch (format) {
case OutputFormat::Markdown:
list_strategy = make_unique<MarkdownListStrategy>();
break;
case OutputFormat::Html:
list_strategy = make_unique<HtmlListStrategy>();
break;
default:
throw runtime_error("Unsupported strategy.");
}
}
string str() const { return oss.str(); }
private:
ostringstream oss;
// Pointer or reference to allow dynamic polymorphism
unique_ptr<ListStrategy> list_strategy;
};
int main() {
// markdown
TextProcessor tp;
tp.set_output_format(OutputFormat::Markdown);
tp.append_list({"foo", "bar", "baz"});
cout << tp.str() << endl;
// html
tp.clear();
tp.set_output_format(OutputFormat::Html);
tp.append_list({"foo", "bar", "baz"});
cout << tp.str() << endl;
return 0;
}