mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-10-14 00:16:48 +00:00
* 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 <md.saiful@revesoft.com>
This commit is contained in:
1 parent
37b92e4b77
commit
9561722bb5
1 file changed
+212
-1
+212
-1
@@ -3,7 +3,7 @@ title: Servant
|
|||||||
category: Behavioral
|
category: Behavioral
|
||||||
language: en
|
language: en
|
||||||
tag:
|
tag:
|
||||||
- Decoupling
|
- Decoupling
|
||||||
---
|
---
|
||||||
|
|
||||||
## Intent
|
## Intent
|
||||||
@@ -11,6 +11,217 @@ Servant is used for providing some behavior to a group of classes.
|
|||||||
Instead of defining that behavior in each class - or when we cannot factor out
|
Instead of defining that behavior in each class - or when we cannot factor out
|
||||||
this behavior in the common parent class - it is defined once in the Servant.
|
this behavior in the common parent class - it is defined once in the Servant.
|
||||||
|
|
||||||
|
## Explanation
|
||||||
|
|
||||||
|
Real-world example
|
||||||
|
|
||||||
|
> King, Queen, and other royal member of palace need servant to service them for feeding,
|
||||||
|
> organizing drinks, and so on.
|
||||||
|
|
||||||
|
In plain words
|
||||||
|
|
||||||
|
> Ensures one servant object to give some specific services for a group of serviced classes.
|
||||||
|
|
||||||
|
Wikipedia says
|
||||||
|
|
||||||
|
> In software engineering, the servant pattern defines an object used to offer some functionality
|
||||||
|
> to a group of classes without defining that functionality in each of them. A Servant is a class
|
||||||
|
> whose instance (or even just class) provides methods that take care of a desired service, while
|
||||||
|
> objects for which (or with whom) the servant does something, are taken as parameters.
|
||||||
|
|
||||||
|
**Programmatic Example**
|
||||||
|
|
||||||
|
Servant class which can give services to other royal members of palace.
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* Servant.
|
||||||
|
*/
|
||||||
|
public class Servant {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public Servant(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void feed(Royalty r) {
|
||||||
|
r.getFed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void giveWine(Royalty r) {
|
||||||
|
r.getDrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void giveCompliments(Royalty r) {
|
||||||
|
r.receiveCompliments();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we will be hanged.
|
||||||
|
*/
|
||||||
|
public boolean checkIfYouWillBeHanged(List<Royalty> tableGuests) {
|
||||||
|
return tableGuests.stream().allMatch(Royalty::getMood);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Royalty is an interface. It is implemented by King, and Queen classes to get services from servant.
|
||||||
|
|
||||||
|
```java
|
||||||
|
interface Royalty {
|
||||||
|
|
||||||
|
void getFed();
|
||||||
|
|
||||||
|
void getDrink();
|
||||||
|
|
||||||
|
void changeMood();
|
||||||
|
|
||||||
|
void receiveCompliments();
|
||||||
|
|
||||||
|
boolean getMood();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
King, class is implementing Royalty interface.
|
||||||
|
```java
|
||||||
|
public class King implements Royalty {
|
||||||
|
|
||||||
|
private boolean isDrunk;
|
||||||
|
private boolean isHungry = true;
|
||||||
|
private boolean isHappy;
|
||||||
|
private boolean complimentReceived;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getFed() {
|
||||||
|
isHungry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getDrink() {
|
||||||
|
isDrunk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveCompliments() {
|
||||||
|
complimentReceived = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changeMood() {
|
||||||
|
if (!isHungry && isDrunk) {
|
||||||
|
isHappy = true;
|
||||||
|
}
|
||||||
|
if (complimentReceived) {
|
||||||
|
isHappy = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMood() {
|
||||||
|
return isHappy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Queen, class is implementing Royalty interface.
|
||||||
|
```java
|
||||||
|
public class Queen implements Royalty {
|
||||||
|
|
||||||
|
private boolean isDrunk = true;
|
||||||
|
private boolean isHungry;
|
||||||
|
private boolean isHappy;
|
||||||
|
private boolean isFlirty = true;
|
||||||
|
private boolean complimentReceived;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getFed() {
|
||||||
|
isHungry = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getDrink() {
|
||||||
|
isDrunk = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveCompliments() {
|
||||||
|
complimentReceived = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changeMood() {
|
||||||
|
if (complimentReceived && isFlirty && isDrunk && !isHungry) {
|
||||||
|
isHappy = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getMood() {
|
||||||
|
return isHappy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFlirtiness(boolean f) {
|
||||||
|
this.isFlirty = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Then in order to use:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
private static final Servant jenkins = new Servant("Jenkins");
|
||||||
|
private static final Servant travis = new Servant("Travis");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Program entry point.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
scenario(jenkins, 1);
|
||||||
|
scenario(travis, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can add a List with enum Actions for variable scenarios.
|
||||||
|
*/
|
||||||
|
public static void scenario(Servant servant, int compliment) {
|
||||||
|
var k = new King();
|
||||||
|
var q = new Queen();
|
||||||
|
|
||||||
|
var guests = List.of(k, q);
|
||||||
|
|
||||||
|
// feed
|
||||||
|
servant.feed(k);
|
||||||
|
servant.feed(q);
|
||||||
|
// serve drinks
|
||||||
|
servant.giveWine(k);
|
||||||
|
servant.giveWine(q);
|
||||||
|
// compliment
|
||||||
|
servant.giveCompliments(guests.get(compliment));
|
||||||
|
|
||||||
|
// outcome of the night
|
||||||
|
guests.forEach(Royalty::changeMood);
|
||||||
|
|
||||||
|
// check your luck
|
||||||
|
if (servant.checkIfYouWillBeHanged(guests)) {
|
||||||
|
LOGGER.info("{} will live another day", servant.name);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Poor {}. His days are numbered", servant.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The console output
|
||||||
|
|
||||||
|
```
|
||||||
|
Jenkins will live another day
|
||||||
|
Poor Travis. His days are numbered
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Class diagram
|
## Class diagram
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user