Skip to content

Commit

Permalink
#590 Add explanation for Chain of Responsibility
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed Sep 19, 2017
1 parent 1b0f55c commit eb36033
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 275 deletions.
126 changes: 125 additions & 1 deletion chain/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,131 @@ Avoid coupling the sender of a request to its receiver by giving
more than one object a chance to handle the request. Chain the receiving
objects and pass the request along the chain until an object handles it.

![alt text](./etc/chain_1.png "Chain of Responsibility")
## Explanation

Real world example

> The Orc King gives loud orders to his army. The closest one to react is the commander, then officer and then soldier. The commander, officer and soldier here form a chain of responsibility.
In plain words

> It helps building a chain of objects. Request enters from one end and keeps going from object to object till it finds the suitable handler.
Wikipedia says

> In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
**Programmatic Example**

Translating our example with orcs from above. First we have the request class

```
public class Request {
private final RequestType requestType;
private final String requestDescription;
private boolean handled;
public Request(final RequestType requestType, final String requestDescription) {
this.requestType = Objects.requireNonNull(requestType);
this.requestDescription = Objects.requireNonNull(requestDescription);
}
public String getRequestDescription() { return requestDescription; }
public RequestType getRequestType() { return requestType; }
public void markHandled() { this.handled = true; }
public boolean isHandled() { return this.handled; }
@Override
public String toString() { return getRequestDescription(); }
}
public enum RequestType {
DEFEND_CASTLE, TORTURE_PRISONER, COLLECT_TAX
}
```

Then the request handler hierarchy

```
public abstract class RequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestHandler.class);
private RequestHandler next;
public RequestHandler(RequestHandler next) {
this.next = next;
}
public void handleRequest(Request req) {
if (next != null) {
next.handleRequest(req);
}
}
protected void printHandling(Request req) {
LOGGER.info("{} handling request \"{}\"", this, req);
}
@Override
public abstract String toString();
}
public class OrcCommander extends RequestHandler {
public OrcCommander(RequestHandler handler) {
super(handler);
}
@Override
public void handleRequest(Request req) {
if (req.getRequestType().equals(RequestType.DEFEND_CASTLE)) {
printHandling(req);
req.markHandled();
} else {
super.handleRequest(req);
}
}
@Override
public String toString() {
return "Orc commander";
}
}
// OrcOfficer and OrcSoldier are defined similarly as OrcCommander
```

Then we have the Orc King who gives the orders and forms the chain

```
public class OrcKing {
RequestHandler chain;
public OrcKing() {
buildChain();
}
private void buildChain() {
chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
}
public void makeRequest(Request req) {
chain.handleRequest(req);
}
}
```

Then it is used as follows

```
OrcKing king = new OrcKing();
king.makeRequest(new Request(RequestType.DEFEND_CASTLE, "defend castle")); // Orc commander handling request "defend castle"
king.makeRequest(new Request(RequestType.TORTURE_PRISONER, "torture prisoner")); // Orc officer handling request "torture prisoner"
king.makeRequest(new Request(RequestType.COLLECT_TAX, "collect tax")); // Orc soldier handling request "collect tax"
```

## Applicability
Use Chain of Responsibility when
Expand Down
Binary file removed chain/etc/chain.png
Binary file not shown.
109 changes: 0 additions & 109 deletions chain/etc/chain.ucls

This file was deleted.

61 changes: 0 additions & 61 deletions chain/etc/chain.urm.puml

This file was deleted.

Binary file removed chain/etc/chain_1.png
Binary file not shown.
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@
<param>decorator</param>
<param>facade</param>
<param>flyweight</param>
<param>proxy</param>
<param>chain</param>
</skipForProjects>
</configuration>
</plugin>
Expand Down
Binary file removed proxy/etc/proxy.png
Binary file not shown.
72 changes: 0 additions & 72 deletions proxy/etc/proxy.ucls

This file was deleted.

Loading

0 comments on commit eb36033

Please sign in to comment.