Skip to content

Commit 6eb48b4

Browse files
authored
Merge branch 'master' into busy-loop
2 parents 3b67748 + f8c7c04 commit 6eb48b4

File tree

7 files changed

+215
-41
lines changed

7 files changed

+215
-41
lines changed

dynamic-proxy/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
<dependency>
3939
<groupId>com.fasterxml.jackson.core</groupId>
4040
<artifactId>jackson-core</artifactId>
41-
<version>2.17.0</version>
41+
<version>2.17.1</version>
4242
</dependency>
4343
<dependency>
4444
<groupId>com.fasterxml.jackson.core</groupId>

event-sourcing/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
<dependency>
4343
<groupId>com.fasterxml.jackson.core</groupId>
4444
<artifactId>jackson-core</artifactId>
45-
<version>2.17.0</version>
45+
<version>2.17.1</version>
4646
</dependency>
4747
<dependency>
4848
<groupId>com.fasterxml.jackson.core</groupId>

front-controller/README.md

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Wikipedia says
3636

3737
The Front Controller design pattern is a pattern that provides a centralized entry point for handling all requests in a web application. It ensures that request handling is managed consistently and efficiently across an application.
3838

39-
In the provided code, we can see an example of the Front Controller pattern in the `App` and `FrontController` classes.
39+
In the provided code, we can see an example of the Front Controller pattern in the `App`, `FrontController` and `Dispatcher` classes.
4040

4141
The `App` class is the entry point of the application. It creates an instance of `FrontController` and uses it to handle various requests.
4242

@@ -52,33 +52,55 @@ public class App {
5252
}
5353
```
5454

55-
The `FrontController` class is the front controller in this example. It handles all requests and routes them to the appropriate handlers.
55+
The `FrontController` class is the front controller in this example. It handles all requests and delegates them to the `Dispatcher`.
5656

5757
```java
5858
public class FrontController {
5959

60-
public void handleRequest(String request) {
61-
Command command;
62-
63-
switch (request) {
64-
case "Archer":
65-
command = new ArcherCommand();
66-
break;
67-
case "Catapult":
68-
command = new CatapultCommand();
69-
break;
70-
default:
71-
command = new UnknownCommand();
60+
private final Dispatcher dispatcher;
61+
62+
public FrontController() {
63+
this.dispatcher = new Dispatcher();
7264
}
7365

66+
public void handleRequest(String request) {
67+
dispatcher.dispatch(request);
68+
}
69+
}
70+
```
71+
72+
The `Dispatcher` class is responsible for handling the dispatching of requests to the appropriate command. It retrieves the corresponding command based on the request and invokes the command's process method to handle the business logic.
73+
74+
```java
75+
public class Dispatcher {
76+
77+
public void dispatch(String request) {
78+
var command = getCommand(request);
7479
command.process();
7580
}
81+
82+
Command getCommand(String request) {
83+
var commandClass = getCommandClass(request);
84+
try {
85+
return (Command) commandClass.getDeclaredConstructor().newInstance();
86+
} catch (Exception e) {
87+
throw new ApplicationException(e);
88+
}
89+
}
90+
91+
static Class<?> getCommandClass(String request) {
92+
try {
93+
return Class.forName("com.iluwatar.front.controller." + request + "Command");
94+
} catch (ClassNotFoundException e) {
95+
return UnknownCommand.class;
96+
}
97+
}
7698
}
7799
```
78100

79-
In this example, when a request is received, the `FrontController` creates a command object based on the request and calls its `process` method. The command object is responsible for handling the request and rendering the appropriate view.
101+
In this example, when a request is received, the `FrontController` delegates the request to the `Dispatcher`, which creates a command object based on the request and calls its `process` method. The command object is responsible for handling the request and rendering the appropriate view.
80102

81-
This is a basic example of the Front Controller pattern, where all requests are handled by a single controller, ensuring consistent and efficient request handling.
103+
This is a basic example of the Front Controller pattern, where all requests are handled by a single controller and dispatcher, ensuring consistent and efficient request handling.
82104

83105
## Class diagram
84106

front-controller/src/main/java/com/iluwatar/front/controller/App.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
package com.iluwatar.front.controller;
2626

2727
/**
28-
* The Front Controller is a presentation tier pattern. Essentially it defines a controller that
28+
* The Front Controller is a presentation tier pattern. Essentially, it defines a controller that
2929
* handles all requests for a website.
3030
*
3131
* <p>The Front Controller pattern consolidates request handling through a single handler object (
32-
* {@link FrontController}). This object can carry out the common the behavior such as
33-
* authorization, request logging and routing requests to corresponding views.
32+
* {@link FrontController}). This object can carry out common behavior such as authorization,
33+
* request logging and routing requests to corresponding views.
3434
*
35-
* <p>Typically the requests are mapped to command objects ({@link Command}) which then display the
35+
* <p>Typically, the requests are mapped to command objects ({@link Command}) which then display the
3636
* correct view ({@link View}).
3737
*
3838
* <p>In this example we have implemented two views: {@link ArcherView} and {@link CatapultView}.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.front.controller;
26+
27+
/**
28+
* The Dispatcher class is responsible for handling the dispatching of requests to the appropriate
29+
* command. It retrieves the corresponding command based on the request and invokes the command's
30+
* process method to handle the business logic.
31+
*/
32+
public class Dispatcher {
33+
34+
/**
35+
* Dispatches the request to the appropriate command.
36+
*
37+
* @param request the request to be handled
38+
*/
39+
public void dispatch(String request) {
40+
var command = getCommand(request);
41+
command.process();
42+
}
43+
44+
/**
45+
* Retrieves the appropriate command instance for the given request.
46+
*
47+
* @param request the request to be handled
48+
* @return the command instance corresponding to the request
49+
*/
50+
Command getCommand(String request) {
51+
var commandClass = getCommandClass(request);
52+
try {
53+
return (Command) commandClass.getDeclaredConstructor().newInstance();
54+
} catch (Exception e) {
55+
throw new ApplicationException(e);
56+
}
57+
}
58+
59+
/**
60+
* Retrieves the Class object for the command corresponding to the given request.
61+
*
62+
* @param request the request to be handled
63+
* @return the Class object of the command corresponding to the request
64+
*/
65+
static Class<?> getCommandClass(String request) {
66+
try {
67+
return Class.forName("com.iluwatar.front.controller." + request + "Command");
68+
} catch (ClassNotFoundException e) {
69+
return UnknownCommand.class;
70+
}
71+
}
72+
}

front-controller/src/main/java/com/iluwatar/front/controller/FrontController.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,19 @@
2525
package com.iluwatar.front.controller;
2626

2727
/**
28-
* FrontController is the handler class that takes in all the requests and renders the correct
29-
* response.
28+
* The FrontController is responsible for handling all incoming requests. It delegates
29+
* the processing of requests to the Dispatcher, which then determines the appropriate
30+
* command and view to render the correct response.
3031
*/
3132
public class FrontController {
3233

33-
public void handleRequest(String request) {
34-
var command = getCommand(request);
35-
command.process();
36-
}
34+
private final Dispatcher dispatcher;
3735

38-
private Command getCommand(String request) {
39-
var commandClass = getCommandClass(request);
40-
try {
41-
return (Command) commandClass.getDeclaredConstructor().newInstance();
42-
} catch (Exception e) {
43-
throw new ApplicationException(e);
44-
}
36+
public FrontController() {
37+
this.dispatcher = new Dispatcher();
4538
}
4639

47-
private static Class<?> getCommandClass(String request) {
48-
try {
49-
return Class.forName("com.iluwatar.front.controller." + request + "Command");
50-
} catch (ClassNotFoundException e) {
51-
return UnknownCommand.class;
52-
}
40+
public void handleRequest(String request) {
41+
dispatcher.dispatch(request);
5342
}
5443
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt).
3+
*
4+
* The MIT License
5+
* Copyright © 2014-2022 Ilkka Seppälä
6+
*
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy
8+
* of this software and associated documentation files (the "Software"), to deal
9+
* in the Software without restriction, including without limitation the rights
10+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
* copies of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be included in
15+
* all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
* THE SOFTWARE.
24+
*/
25+
package com.iluwatar.front.controller;
26+
27+
import org.junit.jupiter.api.BeforeEach;
28+
import org.junit.jupiter.api.Test;
29+
30+
import static org.junit.jupiter.api.Assertions.*;
31+
import static org.mockito.Mockito.*;
32+
33+
class DispatcherTest {
34+
35+
private Dispatcher dispatcher;
36+
37+
@BeforeEach
38+
public void setUp() {
39+
dispatcher = new Dispatcher();
40+
}
41+
42+
@Test
43+
void testDispatchKnownCommand() {
44+
Command mockCommand = mock(ArcherCommand.class);
45+
dispatcher = spy(dispatcher);
46+
doReturn(mockCommand).when(dispatcher).getCommand("Archer");
47+
48+
dispatcher.dispatch("Archer");
49+
50+
verify(mockCommand, times(1)).process();
51+
}
52+
53+
@Test
54+
void testDispatchUnknownCommand() {
55+
Command mockCommand = mock(UnknownCommand.class);
56+
dispatcher = spy(dispatcher);
57+
doReturn(mockCommand).when(dispatcher).getCommand("Unknown");
58+
59+
dispatcher.dispatch("Unknown");
60+
61+
verify(mockCommand, times(1)).process();
62+
}
63+
64+
@Test
65+
void testGetCommandKnown() {
66+
Command command = dispatcher.getCommand("Archer");
67+
assertNotNull(command);
68+
assertTrue(command instanceof ArcherCommand);
69+
}
70+
71+
@Test
72+
void testGetCommandUnknown() {
73+
Command command = dispatcher.getCommand("Unknown");
74+
assertNotNull(command);
75+
assertTrue(command instanceof UnknownCommand);
76+
}
77+
78+
@Test
79+
void testGetCommandClassKnown() {
80+
Class<?> commandClass = Dispatcher.getCommandClass("Archer");
81+
assertNotNull(commandClass);
82+
assertEquals(ArcherCommand.class, commandClass);
83+
}
84+
85+
@Test
86+
void testGetCommandClassUnknown() {
87+
Class<?> commandClass = Dispatcher.getCommandClass("Unknown");
88+
assertNotNull(commandClass);
89+
assertEquals(UnknownCommand.class, commandClass);
90+
}
91+
}

0 commit comments

Comments
 (0)