diff --git a/chain-of-responsibility/README.md b/chain-of-responsibility/README.md index 409915209..8f1fc9918 100644 --- a/chain-of-responsibility/README.md +++ b/chain-of-responsibility/README.md @@ -118,18 +118,24 @@ The Orc King gives the orders and forms the chain. ```java public class OrcKing { - RequestHandler chain; + + private List handlers; public OrcKing() { buildChain(); } private void buildChain() { - chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null))); + handlers = Arrays.asList(new OrcCommander(), new OrcOfficer(), new OrcSoldier()); } public void makeRequest(Request req) { - chain.handleRequest(req); + handlers + .stream() + .sorted(Comparator.comparing(RequestHandler::getPriority)) + .filter(handler -> handler.canHandleRequest(req)) + .findFirst() + .ifPresent(handler -> handler.handle(req)); } } ``` diff --git a/chain-of-responsibility/etc/chain-of-responsibility.urm.png b/chain-of-responsibility/etc/chain-of-responsibility.urm.png index c3a4c80ba..af1bd1054 100644 Binary files a/chain-of-responsibility/etc/chain-of-responsibility.urm.png and b/chain-of-responsibility/etc/chain-of-responsibility.urm.png differ diff --git a/chain-of-responsibility/etc/chain-of-responsibility.urm.puml b/chain-of-responsibility/etc/chain-of-responsibility.urm.puml index 43c78a042..b548cab81 100644 --- a/chain-of-responsibility/etc/chain-of-responsibility.urm.puml +++ b/chain-of-responsibility/etc/chain-of-responsibility.urm.puml @@ -5,25 +5,34 @@ package com.iluwatar.chain { + main(args : String[]) {static} } class OrcCommander { - + OrcCommander(handler : RequestHandler) - + handleRequest(req : Request) - + toString() : String + - LOGGER : Logger {static} + + OrcCommander() + + canHandleRequest(req : Request) : boolean + + getPriority() : int + + handle(req : Request) + + name() : String } class OrcKing { - - chain : RequestHandler + - handlers : List + OrcKing() - buildChain() + makeRequest(req : Request) } class OrcOfficer { - + OrcOfficer(handler : RequestHandler) - + handleRequest(req : Request) - + toString() : String + - LOGGER : Logger {static} + + OrcOfficer() + + canHandleRequest(req : Request) : boolean + + getPriority() : int + + handle(req : Request) + + name() : String } class OrcSoldier { - + OrcSoldier(handler : RequestHandler) - + handleRequest(req : Request) - + toString() : String + - LOGGER : Logger {static} + + OrcSoldier() + + canHandleRequest(req : Request) : boolean + + getPriority() : int + + handle(req : Request) + + name() : String } class Request { - handled : boolean @@ -36,13 +45,11 @@ package com.iluwatar.chain { + markHandled() + toString() : String } - abstract class RequestHandler { - - LOGGER : Logger {static} - - next : RequestHandler - + RequestHandler(next : RequestHandler) - + handleRequest(req : Request) - # printHandling(req : Request) - + toString() : String {abstract} + interface RequestHandler { + + canHandleRequest(Request) : boolean {abstract} + + getPriority() : int {abstract} + + handle(Request) {abstract} + + name() : String {abstract} } enum RequestType { + COLLECT_TAX {static} @@ -52,10 +59,9 @@ package com.iluwatar.chain { + values() : RequestType[] {static} } } -OrcKing --> "-chain" RequestHandler -RequestHandler --> "-next" RequestHandler +OrcKing --> "-handlers" RequestHandler Request --> "-requestType" RequestType -OrcCommander --|> RequestHandler -OrcOfficer --|> RequestHandler -OrcSoldier --|> RequestHandler +OrcCommander ..|> RequestHandler +OrcOfficer ..|> RequestHandler +OrcSoldier ..|> RequestHandler @enduml \ No newline at end of file diff --git a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcCommander.java b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcCommander.java index d99bd2142..70ea09463 100644 --- a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcCommander.java +++ b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcCommander.java @@ -24,27 +24,31 @@ */ package com.iluwatar.chain; +import lombok.extern.slf4j.Slf4j; + /** * OrcCommander. */ -public class OrcCommander extends RequestHandler { - - public OrcCommander(RequestHandler handler) { - super(handler); +@Slf4j +public class OrcCommander implements RequestHandler { + @Override + public boolean canHandleRequest(Request req) { + return req.getRequestType() == RequestType.DEFEND_CASTLE; } @Override - public void handleRequest(Request req) { - if (RequestType.DEFEND_CASTLE == req.getRequestType()) { - printHandling(req); - req.markHandled(); - } else { - super.handleRequest(req); - } + public int getPriority() { + return 2; } @Override - public String toString() { + public void handle(Request req) { + req.markHandled(); + LOGGER.info("{} handling request \"{}\"", name(), req); + } + + @Override + public String name() { return "Orc commander"; } } diff --git a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcKing.java b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcKing.java index 842ff4197..c01aa151a 100644 --- a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcKing.java +++ b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcKing.java @@ -24,23 +24,34 @@ */ package com.iluwatar.chain; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; + /** * OrcKing makes requests that are handled by the chain. */ public class OrcKing { - private RequestHandler chain; + private List handlers; public OrcKing() { buildChain(); } private void buildChain() { - chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null))); + handlers = Arrays.asList(new OrcCommander(), new OrcOfficer(), new OrcSoldier()); } + /** + * Handle request by the chain. + */ public void makeRequest(Request req) { - chain.handleRequest(req); + handlers + .stream() + .sorted(Comparator.comparing(RequestHandler::getPriority)) + .filter(handler -> handler.canHandleRequest(req)) + .findFirst() + .ifPresent(handler -> handler.handle(req)); } - } diff --git a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcOfficer.java b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcOfficer.java index b99b36ff5..7138a001c 100644 --- a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcOfficer.java +++ b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcOfficer.java @@ -24,28 +24,32 @@ */ package com.iluwatar.chain; +import lombok.extern.slf4j.Slf4j; + /** * OrcOfficer. */ -public class OrcOfficer extends RequestHandler { - - public OrcOfficer(RequestHandler handler) { - super(handler); +@Slf4j +public class OrcOfficer implements RequestHandler { + @Override + public boolean canHandleRequest(Request req) { + return req.getRequestType() == RequestType.TORTURE_PRISONER; } @Override - public void handleRequest(Request req) { - if (RequestType.TORTURE_PRISONER == req.getRequestType()) { - printHandling(req); - req.markHandled(); - } else { - super.handleRequest(req); - } + public int getPriority() { + return 3; } @Override - public String toString() { + public void handle(Request req) { + req.markHandled(); + LOGGER.info("{} handling request \"{}\"", name(), req); + } + + @Override + public String name() { return "Orc officer"; } - } + diff --git a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcSoldier.java b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcSoldier.java index fd906620a..6650b3474 100644 --- a/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcSoldier.java +++ b/chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcSoldier.java @@ -24,27 +24,31 @@ */ package com.iluwatar.chain; +import lombok.extern.slf4j.Slf4j; + /** * OrcSoldier. */ -public class OrcSoldier extends RequestHandler { - - public OrcSoldier(RequestHandler handler) { - super(handler); +@Slf4j +public class OrcSoldier implements RequestHandler { + @Override + public boolean canHandleRequest(Request req) { + return req.getRequestType() == RequestType.COLLECT_TAX; } @Override - public void handleRequest(Request req) { - if (RequestType.COLLECT_TAX == req.getRequestType()) { - printHandling(req); - req.markHandled(); - } else { - super.handleRequest(req); - } + public int getPriority() { + return 1; } @Override - public String toString() { + public void handle(Request req) { + req.markHandled(); + LOGGER.info("{} handling request \"{}\"", name(), req); + } + + @Override + public String name() { return "Orc soldier"; } } diff --git a/chain-of-responsibility/src/main/java/com/iluwatar/chain/RequestHandler.java b/chain-of-responsibility/src/main/java/com/iluwatar/chain/RequestHandler.java index 7625a45b8..ca46c44bb 100644 --- a/chain-of-responsibility/src/main/java/com/iluwatar/chain/RequestHandler.java +++ b/chain-of-responsibility/src/main/java/com/iluwatar/chain/RequestHandler.java @@ -24,31 +24,16 @@ */ package com.iluwatar.chain; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; - /** * RequestHandler. */ -@Slf4j -@AllArgsConstructor -public abstract class RequestHandler { +public interface RequestHandler { - private final RequestHandler next; + boolean canHandleRequest(Request req); - /** - * Request handler. - */ - public void handleRequest(Request req) { - if (next != null) { - next.handleRequest(req); - } - } + int getPriority(); - protected void printHandling(Request req) { - LOGGER.info("{} handling request \"{}\"", this, req); - } + void handle(Request req); - @Override - public abstract String toString(); + String name(); }