Skip to content

Commit 1ea98bb

Browse files
authored
enhancement: iluwatar#1947 implement chain of responsibilities with java stream (iluwatar#2123)
1 parent 4108f86 commit 1ea98bb

File tree

8 files changed

+103
-83
lines changed

8 files changed

+103
-83
lines changed

chain-of-responsibility/README.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,24 @@ The Orc King gives the orders and forms the chain.
118118

119119
```java
120120
public class OrcKing {
121-
RequestHandler chain;
121+
122+
private List<RequestHandler> handlers;
122123

123124
public OrcKing() {
124125
buildChain();
125126
}
126127

127128
private void buildChain() {
128-
chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
129+
handlers = Arrays.asList(new OrcCommander(), new OrcOfficer(), new OrcSoldier());
129130
}
130131

131132
public void makeRequest(Request req) {
132-
chain.handleRequest(req);
133+
handlers
134+
.stream()
135+
.sorted(Comparator.comparing(RequestHandler::getPriority))
136+
.filter(handler -> handler.canHandleRequest(req))
137+
.findFirst()
138+
.ifPresent(handler -> handler.handle(req));
133139
}
134140
}
135141
```
Loading

chain-of-responsibility/etc/chain-of-responsibility.urm.puml

+28-22
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,34 @@ package com.iluwatar.chain {
55
+ main(args : String[]) {static}
66
}
77
class OrcCommander {
8-
+ OrcCommander(handler : RequestHandler)
9-
+ handleRequest(req : Request)
10-
+ toString() : String
8+
- LOGGER : Logger {static}
9+
+ OrcCommander()
10+
+ canHandleRequest(req : Request) : boolean
11+
+ getPriority() : int
12+
+ handle(req : Request)
13+
+ name() : String
1114
}
1215
class OrcKing {
13-
- chain : RequestHandler
16+
- handlers : List<RequestHandler>
1417
+ OrcKing()
1518
- buildChain()
1619
+ makeRequest(req : Request)
1720
}
1821
class OrcOfficer {
19-
+ OrcOfficer(handler : RequestHandler)
20-
+ handleRequest(req : Request)
21-
+ toString() : String
22+
- LOGGER : Logger {static}
23+
+ OrcOfficer()
24+
+ canHandleRequest(req : Request) : boolean
25+
+ getPriority() : int
26+
+ handle(req : Request)
27+
+ name() : String
2228
}
2329
class OrcSoldier {
24-
+ OrcSoldier(handler : RequestHandler)
25-
+ handleRequest(req : Request)
26-
+ toString() : String
30+
- LOGGER : Logger {static}
31+
+ OrcSoldier()
32+
+ canHandleRequest(req : Request) : boolean
33+
+ getPriority() : int
34+
+ handle(req : Request)
35+
+ name() : String
2736
}
2837
class Request {
2938
- handled : boolean
@@ -36,13 +45,11 @@ package com.iluwatar.chain {
3645
+ markHandled()
3746
+ toString() : String
3847
}
39-
abstract class RequestHandler {
40-
- LOGGER : Logger {static}
41-
- next : RequestHandler
42-
+ RequestHandler(next : RequestHandler)
43-
+ handleRequest(req : Request)
44-
# printHandling(req : Request)
45-
+ toString() : String {abstract}
48+
interface RequestHandler {
49+
+ canHandleRequest(Request) : boolean {abstract}
50+
+ getPriority() : int {abstract}
51+
+ handle(Request) {abstract}
52+
+ name() : String {abstract}
4653
}
4754
enum RequestType {
4855
+ COLLECT_TAX {static}
@@ -52,10 +59,9 @@ package com.iluwatar.chain {
5259
+ values() : RequestType[] {static}
5360
}
5461
}
55-
OrcKing --> "-chain" RequestHandler
56-
RequestHandler --> "-next" RequestHandler
62+
OrcKing --> "-handlers" RequestHandler
5763
Request --> "-requestType" RequestType
58-
OrcCommander --|> RequestHandler
59-
OrcOfficer --|> RequestHandler
60-
OrcSoldier --|> RequestHandler
64+
OrcCommander ..|> RequestHandler
65+
OrcOfficer ..|> RequestHandler
66+
OrcSoldier ..|> RequestHandler
6167
@enduml

chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcCommander.java

+15-11
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,31 @@
2424
*/
2525
package com.iluwatar.chain;
2626

27+
import lombok.extern.slf4j.Slf4j;
28+
2729
/**
2830
* OrcCommander.
2931
*/
30-
public class OrcCommander extends RequestHandler {
32+
@Slf4j
33+
public class OrcCommander implements RequestHandler {
34+
@Override
35+
public boolean canHandleRequest(Request req) {
36+
return req.getRequestType() == RequestType.DEFEND_CASTLE;
37+
}
3138

32-
public OrcCommander(RequestHandler handler) {
33-
super(handler);
39+
@Override
40+
public int getPriority() {
41+
return 2;
3442
}
3543

3644
@Override
37-
public void handleRequest(Request req) {
38-
if (RequestType.DEFEND_CASTLE == req.getRequestType()) {
39-
printHandling(req);
40-
req.markHandled();
41-
} else {
42-
super.handleRequest(req);
43-
}
45+
public void handle(Request req) {
46+
req.markHandled();
47+
LOGGER.info("{} handling request \"{}\"", name(), req);
4448
}
4549

4650
@Override
47-
public String toString() {
51+
public String name() {
4852
return "Orc commander";
4953
}
5054
}

chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcKing.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,34 @@
2424
*/
2525
package com.iluwatar.chain;
2626

27+
import java.util.Arrays;
28+
import java.util.Comparator;
29+
import java.util.List;
30+
2731
/**
2832
* OrcKing makes requests that are handled by the chain.
2933
*/
3034
public class OrcKing {
3135

32-
private RequestHandler chain;
36+
private List<RequestHandler> handlers;
3337

3438
public OrcKing() {
3539
buildChain();
3640
}
3741

3842
private void buildChain() {
39-
chain = new OrcCommander(new OrcOfficer(new OrcSoldier(null)));
43+
handlers = Arrays.asList(new OrcCommander(), new OrcOfficer(), new OrcSoldier());
4044
}
4145

46+
/**
47+
* Handle request by the chain.
48+
*/
4249
public void makeRequest(Request req) {
43-
chain.handleRequest(req);
50+
handlers
51+
.stream()
52+
.sorted(Comparator.comparing(RequestHandler::getPriority))
53+
.filter(handler -> handler.canHandleRequest(req))
54+
.findFirst()
55+
.ifPresent(handler -> handler.handle(req));
4456
}
45-
4657
}

chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcOfficer.java

+16-12
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,32 @@
2424
*/
2525
package com.iluwatar.chain;
2626

27+
import lombok.extern.slf4j.Slf4j;
28+
2729
/**
2830
* OrcOfficer.
2931
*/
30-
public class OrcOfficer extends RequestHandler {
32+
@Slf4j
33+
public class OrcOfficer implements RequestHandler {
34+
@Override
35+
public boolean canHandleRequest(Request req) {
36+
return req.getRequestType() == RequestType.TORTURE_PRISONER;
37+
}
3138

32-
public OrcOfficer(RequestHandler handler) {
33-
super(handler);
39+
@Override
40+
public int getPriority() {
41+
return 3;
3442
}
3543

3644
@Override
37-
public void handleRequest(Request req) {
38-
if (RequestType.TORTURE_PRISONER == req.getRequestType()) {
39-
printHandling(req);
40-
req.markHandled();
41-
} else {
42-
super.handleRequest(req);
43-
}
45+
public void handle(Request req) {
46+
req.markHandled();
47+
LOGGER.info("{} handling request \"{}\"", name(), req);
4448
}
4549

4650
@Override
47-
public String toString() {
51+
public String name() {
4852
return "Orc officer";
4953
}
50-
5154
}
55+

chain-of-responsibility/src/main/java/com/iluwatar/chain/OrcSoldier.java

+15-11
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,31 @@
2424
*/
2525
package com.iluwatar.chain;
2626

27+
import lombok.extern.slf4j.Slf4j;
28+
2729
/**
2830
* OrcSoldier.
2931
*/
30-
public class OrcSoldier extends RequestHandler {
32+
@Slf4j
33+
public class OrcSoldier implements RequestHandler {
34+
@Override
35+
public boolean canHandleRequest(Request req) {
36+
return req.getRequestType() == RequestType.COLLECT_TAX;
37+
}
3138

32-
public OrcSoldier(RequestHandler handler) {
33-
super(handler);
39+
@Override
40+
public int getPriority() {
41+
return 1;
3442
}
3543

3644
@Override
37-
public void handleRequest(Request req) {
38-
if (RequestType.COLLECT_TAX == req.getRequestType()) {
39-
printHandling(req);
40-
req.markHandled();
41-
} else {
42-
super.handleRequest(req);
43-
}
45+
public void handle(Request req) {
46+
req.markHandled();
47+
LOGGER.info("{} handling request \"{}\"", name(), req);
4448
}
4549

4650
@Override
47-
public String toString() {
51+
public String name() {
4852
return "Orc soldier";
4953
}
5054
}

chain-of-responsibility/src/main/java/com/iluwatar/chain/RequestHandler.java

+5-20
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,16 @@
2424
*/
2525
package com.iluwatar.chain;
2626

27-
import lombok.AllArgsConstructor;
28-
import lombok.extern.slf4j.Slf4j;
29-
3027
/**
3128
* RequestHandler.
3229
*/
33-
@Slf4j
34-
@AllArgsConstructor
35-
public abstract class RequestHandler {
30+
public interface RequestHandler {
3631

37-
private final RequestHandler next;
32+
boolean canHandleRequest(Request req);
3833

39-
/**
40-
* Request handler.
41-
*/
42-
public void handleRequest(Request req) {
43-
if (next != null) {
44-
next.handleRequest(req);
45-
}
46-
}
34+
int getPriority();
4735

48-
protected void printHandling(Request req) {
49-
LOGGER.info("{} handling request \"{}\"", this, req);
50-
}
36+
void handle(Request req);
5137

52-
@Override
53-
public abstract String toString();
38+
String name();
5439
}

0 commit comments

Comments
 (0)