-
Notifications
You must be signed in to change notification settings - Fork 1
/
DynamicAndStaticStrategy.java
137 lines (116 loc) · 3.54 KB
/
DynamicAndStaticStrategy.java
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Strategy pattern - example outputs a list in different formats using both dynamic and static patterns
package behavioral.strategy;
import java.util.List;
import java.util.function.Supplier;
enum OutputFormat
{
MARKDOWN, HTML
}
interface ListStrategy
{
default void start(StringBuilder sb) {} // adding 'default' feels like cheating
void addListItem(StringBuilder sb, String item);
default void end(StringBuilder sb) {}
}
class MarkdownListStrategy implements ListStrategy
{
@Override
public void addListItem(StringBuilder sb, String item)
{
sb.append(" * ").append(item)
.append(System.lineSeparator());
}
}
class HtmlListStrategy implements ListStrategy
{
@Override
public void start(StringBuilder sb)
{
sb.append("<ul>").append(System.lineSeparator());
}
@Override
public void addListItem(StringBuilder sb, String item)
{
sb.append(" <li>")
.append(item)
.append("</li>")
.append(System.lineSeparator());
}
@Override
public void end(StringBuilder sb)
{
sb.append("</ul>").append(System.lineSeparator());
}
}
// To make pattern static, make class generic
class TextProcessor<LS extends ListStrategy>
{
private StringBuilder sb = new StringBuilder();
// private ListStrategy listStrategy; // dynamic way to determine what processor we want
private LS listStrategy; // static approach
// DYNAMIC APPROACH
// public TextProcessor(OutputFormat format)
// {
// setOutputFormat(format);
// }
//
// public void setOutputFormat(OutputFormat format)
// {
// switch (format) {
// case MARKDOWN:
// listStrategy = new MarkdownListStrategy();
// break;
// case HTML:
// listStrategy = new HtmlListStrategy();
// break;
// }
// }
// STATIC APPROACH
public TextProcessor(Supplier<? extends LS> ctor)
{
listStrategy = ctor.get();
}
// Employ the strategy here
public void appendList(List<String> items)
{
listStrategy.start(sb);
for(String item : items)
listStrategy.addListItem(sb, item); // key method of strategy pattern
listStrategy.end(sb);
}
public void clear()
{
sb.setLength(0);
}
@Override
public String toString()
{
return sb.toString();
}
}
class StrategyDemo
{
public static void main(String[] args)
{
// DYNAMIC APPROACH
// The reason the strategy is dynamic is that you can switch strategies at runtime
// TextProcessor tp = new TextProcessor(OutputFormat.MARKDOWN);
// tp.appendList(List.of("liberte", "egalite", "fraternite"));
// System.out.println(tp);
//
// tp.clear();
// tp.setOutputFormat(OutputFormat.HTML); // 'dynamic' as you changed the strategy here
// tp.appendList(List.of("inheritance", "encapsulation", "polymorphism"));
// System.out.println(tp);
// STATIC APPROACH
TextProcessor<MarkdownListStrategy> tp
= new TextProcessor<>(MarkdownListStrategy::new); // passing in the constructor
tp.appendList(List.of("alpha", "beta", "gamma"));
System.out.println(tp);
// Cannot switch strategies with static approach. Need to create new processor
TextProcessor<HtmlListStrategy> tp2
= new TextProcessor<>(HtmlListStrategy::new);
tp2.appendList(List.of("alpha", "beta", "gamma"));
System.out.println(tp2);
}
}