feature: Add Service to Worker Pattern (#2004)

* update service to worker

* update pom.xml and make GiantModel public

* add javadoc for GaintModel
This commit is contained in:
Renjie LIU authored and GitHub committed 2022-09-18 13:36:59 +03:00
1 parent b027d29b29
commit 953af7c66c
19 files changed
+886 -1

No files matched your search

@@ -0,0 +1,61 @@
package com.iluwatar.servicetoworker;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
/**
* The type Action (Worker), which can process user input and perform a specific update on the
* model.
*/
public class Action {
public GiantModel giant;
/**
* Instantiates a new Action.
*
* @param giant the giant
*/
public Action(GiantModel giant) {
this.giant = giant;
}
/**
* Update model based on command.
*
* @param command the command
*/
public void updateModel(Command command) {
setFatigue(command.getFatigue());
setHealth(command.getHealth());
setNourishment(command.getNourishment());
}
/**
* Sets health.
*
* @param health the health
*/
public void setHealth(Health health) {
giant.setHealth(health);
}
/**
* Sets fatigue.
*
* @param fatigue the fatigue
*/
public void setFatigue(Fatigue fatigue) {
giant.setFatigue(fatigue);
}
/**
* Sets nourishment.
*
* @param nourishment the nourishment
*/
public void setNourishment(Nourishment nourishment) {
giant.setNourishment(nourishment);
}
}
@@ -0,0 +1,47 @@
package com.iluwatar.servicetoworker;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
/**
* The front controller intercepts all requests and performs common functions using decorators. The
* front controller passes request information to the dispatcher, which uses the request and an
* internal model to chooses and execute appropriate actions. The actions process user input,
* translating it into appropriate updates to the model. The model applies business rules and stores
* the data persistently. Based on the user input and results of the actions, the dispatcher chooses
* a view. The view transforms the updated model data into a form suitable for the user.
*/
public class App {
/**
* Program entry point.
*
* @param args command line args
*/
public static void main(String[] args) {
// create model, view and controller
var giant1 = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT, Nourishment.SATURATED);
var giant2 = new GiantModel("giant2", Health.DEAD, Fatigue.SLEEPING, Nourishment.STARVING);
var action1 = new Action(giant1);
var action2 = new Action(giant2);
var view = new GiantView();
var dispatcher = new Dispatcher(view);
dispatcher.addAction(action1);
dispatcher.addAction(action2);
var controller = new GiantController(dispatcher);
// initial display
controller.updateView(giant1);
controller.updateView(giant2);
// controller receives some interactions that affect the giant
controller.setCommand(new Command(Fatigue.SLEEPING, Health.HEALTHY, Nourishment.STARVING), 0);
controller.setCommand(new Command(Fatigue.ALERT, Health.HEALTHY, Nourishment.HUNGRY), 1);
// redisplay
controller.updateView(giant1);
controller.updateView(giant2);
// controller receives some interactions that affect the giant
}
}
@@ -0,0 +1,32 @@
package com.iluwatar.servicetoworker;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import lombok.Getter;
/**
* The type Command.
*/
public class Command {
@Getter
private final Fatigue fatigue;
@Getter
private final Health health;
@Getter
private final Nourishment nourishment;
/**
* Instantiates a new Command.
*
* @param fatigue the fatigue
* @param health the health
* @param nourishment the nourishment
*/
public Command(Fatigue fatigue, Health health, Nourishment nourishment) {
this.fatigue = fatigue;
this.health = health;
this.nourishment = nourishment;
}
}
@@ -0,0 +1,55 @@
package com.iluwatar.servicetoworker;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
/**
* The type Dispatcher, which encapsulates worker and view selection based on request information
* and/or an internal navigation model.
*/
public class Dispatcher {
@Getter
private final GiantView giantView;
private final List<Action> actions;
/**
* Instantiates a new Dispatcher.
*
* @param giantView the giant view
*/
public Dispatcher(GiantView giantView) {
this.giantView = giantView;
this.actions = new ArrayList<>();
}
/**
* Add an action.
*
* @param action the action
*/
void addAction(Action action) {
actions.add(action);
}
/**
* Perform an action.
*
* @param s the s
* @param actionIndex the action index
*/
public void performAction(Command s, int actionIndex) {
actions.get(actionIndex).updateModel(s);
}
/**
* Update view.
*
* @param giantModel the giant model
*/
public void updateView(GiantModel giantModel) {
giantView.displayGiant(giantModel);
}
}
@@ -0,0 +1,41 @@
package com.iluwatar.servicetoworker;
import lombok.Getter;
/**
* GiantController can update the giant data and redraw it using the view. Singleton object that
* intercepts all requests and performs common functions.
*/
public class GiantController {
public Dispatcher dispatcher;
/**
* Instantiates a new Giant controller.
*
* @param dispatcher the dispatcher
*/
public GiantController(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
/**
* Sets command to control the dispatcher.
*
* @param s the s
* @param index the index
*/
public void setCommand(Command s, int index) {
dispatcher.performAction(s, index);
}
/**
* Update view. This is a simple implementation, in fact, View can be implemented in a concrete
* way
*
* @param giantModel the giant model
*/
public void updateView(GiantModel giantModel) {
dispatcher.updateView(giantModel);
}
}
@@ -0,0 +1,86 @@
package com.iluwatar.servicetoworker;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import lombok.Getter;
/**
* GiantModel contains the giant data.
*/
public class GiantModel {
private final com.iluwatar.model.view.controller.GiantModel model;
@Getter
private final String name;
/**
* Instantiates a new Giant model.
*
* @param name the name
* @param health the health
* @param fatigue the fatigue
* @param nourishment the nourishment
*/
GiantModel(String name, Health health, Fatigue fatigue, Nourishment nourishment) {
this.name = name;
this.model = new com.iluwatar.model.view.controller.GiantModel(health, fatigue,
nourishment);
}
/**
* Gets health.
*
* @return the health
*/
Health getHealth() {
return model.getHealth();
}
/**
* Sets health.
*
* @param health the health
*/
void setHealth(Health health) {
model.setHealth(health);
}
/**
* Gets fatigue.
*
* @return the fatigue
*/
Fatigue getFatigue() {
return model.getFatigue();
}
void setFatigue(Fatigue fatigue) {
model.setFatigue(fatigue);
}
/**
* Gets nourishment.
*
* @return the nourishment
*/
Nourishment getNourishment() {
return model.getNourishment();
}
/**
* Sets nourishment.
*
* @param nourishment the nourishment
*/
void setNourishment(Nourishment nourishment) {
model.setNourishment(nourishment);
}
@Override
public String toString() {
return String
.format("Giant %s, The giant looks %s, %s and %s.", name,
model.getHealth(), model.getFatigue(), model.getNourishment());
}
}
@@ -0,0 +1,19 @@
package com.iluwatar.servicetoworker;
import lombok.extern.slf4j.Slf4j;
/**
* GiantView displays the giant.
*/
@Slf4j
public class GiantView {
/**
* Display the GiantModel simply.
*
* @param giant the giant
*/
public void displayGiant(GiantModel giant) {
LOGGER.info(giant.toString());
}
}
@@ -0,0 +1,87 @@
package com.iluwatar.servicetoworker;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import org.junit.jupiter.api.Test;
/**
* The type Action test.
*/
class ActionTest {
/**
* Verify if the health value is set properly though the constructor and setter
*/
@Test
void testSetHealth() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
assertEquals(Health.HEALTHY, model.getHealth());
var messageFormat = "Giant giant1, The giant looks %s, alert and saturated.";
for (final var health : Health.values()) {
action.setHealth(health);
assertEquals(health, model.getHealth());
assertEquals(String.format(messageFormat, health), model.toString());
}
}
/**
* Verify if the fatigue level is set properly though the constructor and setter
*/
@Test
void testSetFatigue() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
assertEquals(Fatigue.ALERT, model.getFatigue());
var messageFormat = "Giant giant1, The giant looks healthy, %s and saturated.";
for (final var fatigue : Fatigue.values()) {
action.setFatigue(fatigue);
assertEquals(fatigue, model.getFatigue());
assertEquals(String.format(messageFormat, fatigue), model.toString());
}
}
/**
* Verify if the nourishment level is set properly though the constructor and setter
*/
@Test
void testSetNourishment() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
assertEquals(Nourishment.SATURATED, model.getNourishment());
var messageFormat = "Giant giant1, The giant looks healthy, alert and %s.";
for (final var nourishment : Nourishment.values()) {
action.setNourishment(nourishment);
assertEquals(nourishment, model.getNourishment());
assertEquals(String.format(messageFormat, nourishment), model.toString());
}
}
/**
* Test update model.
*/
@Test
void testUpdateModel() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
assertEquals(Nourishment.SATURATED, model.getNourishment());
for (final var nourishment : Nourishment.values()) {
for (final var fatigue : Fatigue.values()) {
for (final var health : Health.values()) {
Command cmd = new Command(fatigue, health, nourishment);
action.updateModel(cmd);
assertEquals(nourishment, model.getNourishment());
assertEquals(fatigue, model.getFatigue());
assertEquals(health, model.getHealth());
}
}
}
}
}
@@ -0,0 +1,16 @@
package com.iluwatar.servicetoworker;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Application test
*/
class AppTest {
@Test
void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{}));
}
}
@@ -0,0 +1,52 @@
package com.iluwatar.servicetoworker;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import org.junit.jupiter.api.Test;
/**
* The type Dispatcher test.
*/
class DispatcherTest {
/**
* Test perform action.
*/
@Test
void testPerformAction() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
GiantView giantView = new GiantView();
Dispatcher dispatcher = new Dispatcher(giantView);
assertEquals(Nourishment.SATURATED, model.getNourishment());
dispatcher.addAction(action);
for (final var nourishment : Nourishment.values()) {
for (final var fatigue : Fatigue.values()) {
for (final var health : Health.values()) {
Command cmd = new Command(fatigue, health, nourishment);
dispatcher.performAction(cmd, 0);
assertEquals(nourishment, model.getNourishment());
assertEquals(fatigue, model.getFatigue());
assertEquals(health, model.getHealth());
}
}
}
}
@Test
void testUpdateView() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
GiantView giantView = new GiantView();
Dispatcher dispatcher = new Dispatcher(giantView);
assertDoesNotThrow(() -> dispatcher.updateView(model));
}
}
@@ -0,0 +1,49 @@
package com.iluwatar.servicetoworker;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import org.junit.jupiter.api.Test;
/**
* The type Giant controller test.
*/
class GiantControllerTest {
/**
* Test set command.
*/
@Test
void testSetCommand() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
Action action = new Action(model);
GiantView giantView = new GiantView();
Dispatcher dispatcher = new Dispatcher(giantView);
assertEquals(Nourishment.SATURATED, model.getNourishment());
dispatcher.addAction(action);
GiantController controller = new GiantController(dispatcher);
controller.setCommand(new Command(Fatigue.ALERT, Health.HEALTHY, Nourishment.HUNGRY), 0);
assertEquals(Fatigue.ALERT, model.getFatigue());
assertEquals(Health.HEALTHY, model.getHealth());
assertEquals(Nourishment.HUNGRY, model.getNourishment());
}
/**
* Test update view.
*/
@Test
void testUpdateView() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
GiantView giantView = new GiantView();
Dispatcher dispatcher = new Dispatcher(giantView);
GiantController giantController = new GiantController(dispatcher);
assertDoesNotThrow(() -> giantController.updateView(model));
}
}
@@ -0,0 +1,62 @@
package com.iluwatar.servicetoworker;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import org.junit.jupiter.api.Test;
/**
* The type Giant model test.
*/
class GiantModelTest {
/**
* Verify if the health value is set properly though the constructor and setter
*/
@Test
void testSetHealth() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
assertEquals(Health.HEALTHY, model.getHealth());
var messageFormat = "Giant giant1, The giant looks %s, alert and saturated.";
for (final var health : Health.values()) {
model.setHealth(health);
assertEquals(health, model.getHealth());
assertEquals(String.format(messageFormat, health), model.toString());
}
}
/**
* Verify if the fatigue level is set properly though the constructor and setter
*/
@Test
void testSetFatigue() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
assertEquals(Fatigue.ALERT, model.getFatigue());
var messageFormat = "Giant giant1, The giant looks healthy, %s and saturated.";
for (final var fatigue : Fatigue.values()) {
model.setFatigue(fatigue);
assertEquals(fatigue, model.getFatigue());
assertEquals(String.format(messageFormat, fatigue), model.toString());
}
}
/**
* Verify if the nourishment level is set properly though the constructor and setter
*/
@Test
void testSetNourishment() {
final var model = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
assertEquals(Nourishment.SATURATED, model.getNourishment());
var messageFormat = "Giant giant1, The giant looks healthy, alert and %s.";
for (final var nourishment : Nourishment.values()) {
model.setNourishment(nourishment);
assertEquals(nourishment, model.getNourishment());
assertEquals(String.format(messageFormat, nourishment), model.toString());
}
}
}
@@ -0,0 +1,25 @@
package com.iluwatar.servicetoworker;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import com.iluwatar.model.view.controller.Fatigue;
import com.iluwatar.model.view.controller.Health;
import com.iluwatar.model.view.controller.Nourishment;
import org.junit.jupiter.api.Test;
/**
* The type Giant view test.
*/
class GiantViewTest {
/**
* Test dispaly giant.
*/
@Test
void testDispalyGiant() {
GiantModel giantModel = new GiantModel("giant1", Health.HEALTHY, Fatigue.ALERT,
Nourishment.SATURATED);
GiantView giantView = new GiantView();
assertDoesNotThrow(() -> giantView.displayGiant(giantModel));
}
}