1.5.2. Chain of Responsibility Sample Code
From the book:
This pattern is useful when we have code of the form shown in Listing 1.3.
Listing 1.3: Nested if-else-if constructs.
//:~ core/src/main/.../ch01/ChainDemo.java
public void handleWithoutChain(
String key, Consumer<String> processor) {
var item = map1.get(key);
if (item != null) processor.accept(item);
else {
item = map2.get(key);
if (item != null) processor.accept(item);
else {
item = map3.get(key); // ad nauseum
}
}
}
Instead of the multiconditional if-else statement, we create an abstract Handler class. The default implementation of handle() is to pass the call down the chain to the next handler.
Listing 1.4: Chain-of-responsibility handler.
//:~ core/src/main/.../ch01/Handler.java
public abstract class Handler {
private final Handler next;
public Handler(Handler next) {
this.next = next;
}
public void handle(String key, Consumer<String> processor) {
if (next != null) next.handle(key, processor);
}
}
Our MapHandler contains the implementation that calls process(item) if the item is found in our map; else it calls super.handle(key).
Listing 1.5: Concrete handler for maps.
//:~ core/src/main/.../ch01/MapHandler.java
public class MapHandler extends Handler {
private final Map<String, String> map;
public MapHandler(Map<String, String> map, Handler next) {
super(next);
this.map = map;
}
@Override
public void handle(String key, Consumer<String> processor) {
String item = map.get(key);
if (item != null) processor.accept(item);
else super.handle(key, processor);
}
}
Inside our class, we would set up the chain as we see in Listing 1.6.
Listing 1.6: Chain of handlers as field.
//:~ core/src/main/.../ch01/ChainDemo.java
private final Handler chain =
new MapHandler(map1,
new MapHandler(map2,
new MapHandler(map3, null)));
Instead of the complicated if-else-if construct from Listing 1.3, we can write:
Listing 1.7: Using the chain-of-responsibility handler.
//:~ core/src/main/.../ch01/ChainDemo.java
private void handleWithChain(
String key, Consumer<String> processor) {
chain.handle(key, processor);
}
0 comments