Skip to content

Commit 9561722

Browse files
mm-saiful6854Md Saiful Islam
and
Md Saiful Islam
authored
feat: #2260 Add explanation into README.md for Servant pattern (#2586)
* issue id: #2260 explanation: modify README.md file. - add Explanation selection - add Real-world example, under the Explanation selection. Example express the  the king, queen and servant relationship. - add plain-word, wiki say - add programmatic example with code of  king, queen and servant classes. - add console output by running code at local. * fix: #2260 - remove a line from readme.md --------- Co-authored-by: Md Saiful Islam <[email protected]>
1 parent 37b92e4 commit 9561722

File tree

1 file changed

+212
-1
lines changed

1 file changed

+212
-1
lines changed

Diff for: servant/README.md

+212-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,225 @@ title: Servant
33
category: Behavioral
44
language: en
55
tag:
6-
- Decoupling
6+
- Decoupling
77
---
88

99
## Intent
1010
Servant is used for providing some behavior to a group of classes.
1111
Instead of defining that behavior in each class - or when we cannot factor out
1212
this behavior in the common parent class - it is defined once in the Servant.
1313

14+
## Explanation
15+
16+
Real-world example
17+
18+
> King, Queen, and other royal member of palace need servant to service them for feeding,
19+
> organizing drinks, and so on.
20+
21+
In plain words
22+
23+
> Ensures one servant object to give some specific services for a group of serviced classes.
24+
25+
Wikipedia says
26+
27+
> In software engineering, the servant pattern defines an object used to offer some functionality
28+
> to a group of classes without defining that functionality in each of them. A Servant is a class
29+
> whose instance (or even just class) provides methods that take care of a desired service, while
30+
> objects for which (or with whom) the servant does something, are taken as parameters.
31+
32+
**Programmatic Example**
33+
34+
Servant class which can give services to other royal members of palace.
35+
36+
```java
37+
/**
38+
* Servant.
39+
*/
40+
public class Servant {
41+
42+
public String name;
43+
44+
/**
45+
* Constructor.
46+
*/
47+
public Servant(String name) {
48+
this.name = name;
49+
}
50+
51+
public void feed(Royalty r) {
52+
r.getFed();
53+
}
54+
55+
public void giveWine(Royalty r) {
56+
r.getDrink();
57+
}
58+
59+
public void giveCompliments(Royalty r) {
60+
r.receiveCompliments();
61+
}
62+
63+
/**
64+
* Check if we will be hanged.
65+
*/
66+
public boolean checkIfYouWillBeHanged(List<Royalty> tableGuests) {
67+
return tableGuests.stream().allMatch(Royalty::getMood);
68+
}
69+
}
70+
```
71+
72+
Royalty is an interface. It is implemented by King, and Queen classes to get services from servant.
73+
74+
```java
75+
interface Royalty {
76+
77+
void getFed();
78+
79+
void getDrink();
80+
81+
void changeMood();
82+
83+
void receiveCompliments();
84+
85+
boolean getMood();
86+
}
87+
```
88+
King, class is implementing Royalty interface.
89+
```java
90+
public class King implements Royalty {
91+
92+
private boolean isDrunk;
93+
private boolean isHungry = true;
94+
private boolean isHappy;
95+
private boolean complimentReceived;
96+
97+
@Override
98+
public void getFed() {
99+
isHungry = false;
100+
}
101+
102+
@Override
103+
public void getDrink() {
104+
isDrunk = true;
105+
}
106+
107+
public void receiveCompliments() {
108+
complimentReceived = true;
109+
}
110+
111+
@Override
112+
public void changeMood() {
113+
if (!isHungry && isDrunk) {
114+
isHappy = true;
115+
}
116+
if (complimentReceived) {
117+
isHappy = false;
118+
}
119+
}
120+
121+
@Override
122+
public boolean getMood() {
123+
return isHappy;
124+
}
125+
}
126+
```
127+
Queen, class is implementing Royalty interface.
128+
```java
129+
public class Queen implements Royalty {
130+
131+
private boolean isDrunk = true;
132+
private boolean isHungry;
133+
private boolean isHappy;
134+
private boolean isFlirty = true;
135+
private boolean complimentReceived;
136+
137+
@Override
138+
public void getFed() {
139+
isHungry = false;
140+
}
141+
142+
@Override
143+
public void getDrink() {
144+
isDrunk = true;
145+
}
146+
147+
public void receiveCompliments() {
148+
complimentReceived = true;
149+
}
150+
151+
@Override
152+
public void changeMood() {
153+
if (complimentReceived && isFlirty && isDrunk && !isHungry) {
154+
isHappy = true;
155+
}
156+
}
157+
158+
@Override
159+
public boolean getMood() {
160+
return isHappy;
161+
}
162+
163+
public void setFlirtiness(boolean f) {
164+
this.isFlirty = f;
165+
}
166+
167+
}
168+
```
169+
170+
Then in order to use:
171+
172+
```java
173+
public class App {
174+
175+
private static final Servant jenkins = new Servant("Jenkins");
176+
private static final Servant travis = new Servant("Travis");
177+
178+
/**
179+
* Program entry point.
180+
*/
181+
public static void main(String[] args) {
182+
scenario(jenkins, 1);
183+
scenario(travis, 0);
184+
}
185+
186+
/**
187+
* Can add a List with enum Actions for variable scenarios.
188+
*/
189+
public static void scenario(Servant servant, int compliment) {
190+
var k = new King();
191+
var q = new Queen();
192+
193+
var guests = List.of(k, q);
194+
195+
// feed
196+
servant.feed(k);
197+
servant.feed(q);
198+
// serve drinks
199+
servant.giveWine(k);
200+
servant.giveWine(q);
201+
// compliment
202+
servant.giveCompliments(guests.get(compliment));
203+
204+
// outcome of the night
205+
guests.forEach(Royalty::changeMood);
206+
207+
// check your luck
208+
if (servant.checkIfYouWillBeHanged(guests)) {
209+
LOGGER.info("{} will live another day", servant.name);
210+
} else {
211+
LOGGER.info("Poor {}. His days are numbered", servant.name);
212+
}
213+
}
214+
}
215+
```
216+
217+
The console output
218+
219+
```
220+
Jenkins will live another day
221+
Poor Travis. His days are numbered
222+
```
223+
224+
14225
## Class diagram
15226
![alt text](./etc/servant-pattern.png "Servant")
16227

0 commit comments

Comments
 (0)