Repository: iluwatar/java-design-patterns
Issue: Explanation for Servant
Labels: type: feature
epic: documentation

In this issue, let's add a proper explanation for the pattern.

Acceptance criteria

- The pattern's README.md has been amended with an explanation
- The explanation consists of
  - Real world example
  - In plain words
  - Wikipedia says
  - Programmatic example


Issue comments:
Hello. I want to nominate myself for writing explanation about Servant design pattern.
Hi @iluwatar, I would like to take care of the above feature. Please assign it to me.

Pull request review comments:

Patch that resolved the issue:
diff --git a/servant/README.md b/servant/README.md
index bfd06e2bc37a..c6aaf414873d 100644
--- a/servant/README.md
+++ b/servant/README.md
@@ -3,7 +3,7 @@ title: Servant
 category: Behavioral
 language: en
 tag:
- - Decoupling
+- Decoupling
 ---
 
 ## 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
 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
 ![alt text](./etc/servant-pattern.png "Servant")
 


Test patch: