diff --git a/service-to-worker/README.md b/service-to-worker/README.md index bf37a2b9e..353604e4b 100644 --- a/service-to-worker/README.md +++ b/service-to-worker/README.md @@ -3,113 +3,124 @@ title: Service to Worker category: Architectural language: en tag: -- Decoupling + - Business + - Decoupling + - Layered architecture + - Presentation + - Web development --- ## Intent -Combine a controller and dispatcher with views and helpers to handle client requests and prepare a dynamic presentation as the response. Controllers delegate content retrieval to helpers, which manage the population of the intermediate model for the view. A dispatcher is responsible for view management and navigation and can be encapsulated either within a controller or a separate component. +The Service to Worker design pattern combines the Dispatcher View and Service Locator patterns to facilitate the separation of processing, control flow, and view management in web applications. ## Explanation -Real world example +Real-world example -> In the classic MVC pattern, M refers to the business model, V refers to the user interface, and C is the controller. The purpose of using MVC is to separate the implementation code of M and V, so that the same program can use different forms of expression. In the Service to Worker pattern, the C directly controls the display of the V and can receive commands to control the dispatcher indirectly. The dispatcher stores different commands that can be used to modify the `model` with `action`s or to modify the display in the `view`s. +> Imagine a large restaurant chain with a central kitchen and multiple waitstaff. When a customer places an order, the waitstaff (Controller) takes the order and hands it over to the kitchen (Service). The kitchen then processes the order, prepares the dish, and hands it back to the waitstaff. The waitstaff finally delivers the dish to the customer (View). This setup allows the kitchen staff to focus solely on cooking without worrying about customer interactions, while the waitstaff can concentrate on customer service without worrying about the cooking process. In plain words -> Service to Worker Pattern uses Dispatcher to combine the controller and the view to handle client requests and prepare a dynamic presentation as the response. +> Separates the processing logic from the view in web applications to improve maintainability and scalability. **Programmatic Example** -We modified this pattern based on a classic design patterns [Model View Controller Pattern](https://github.com/iluwatar/java-design-patterns/tree/master/model-view-controller) as the Class Diagram and two main classes `Dispatcher` and `Action` have been added. +The Service to Worker design pattern separates the processing logic from the view in web applications to improve maintainability and scalability. It combines the Dispatcher View and Service Locator patterns to facilitate the separation of processing, control flow, and view management in web applications. -The Dispatcher, which encapsulates worker and view selection based on request information and/or an internal navigation model. +In our example, we have a `GiantController` class, which acts as the controller in the Service to Worker pattern. It takes commands and updates the view. The `Dispatcher` class is responsible for performing actions and updating the view. + +Here is the `GiantController` class: ```java -public class Dispatcher { +public class GiantController { - private final GiantView giantView; - private final List actions; + public Dispatcher dispatcher; - /** - * Instantiates a new Dispatcher. - * - * @param giantView the giant view - */ - public Dispatcher(GiantView giantView) { - this.giantView = giantView; - this.actions = new ArrayList<>(); + public GiantController(Dispatcher dispatcher) { + this.dispatcher = dispatcher; } - /** - * Add an action. - * - * @param action the action - */ - void addAction(Action action) { - actions.add(action); + public void setCommand(Command s, int index) { + dispatcher.performAction(s, index); } - /** - * 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); + dispatcher.updateView(giantModel); } } ``` -The Action (Worker), which can process user input and perform a specific update on the model. +In the `GiantController` class, we have a `setCommand` method that takes a `Command` and an index. This method is used to control the dispatcher. The `updateView` method is used to update the view with the provided `GiantModel`. + +The `App` class is the entry point of our application: ```java -public class Action { +public class App { - private final GiantModel giant; + public static void main(String[] args) { + 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); - /** - * Instantiates a new Action. - * - * @param giant the giant - */ - public Action(GiantModel giant) { - this.giant = giant; - } + controller.updateView(giant1); + controller.updateView(giant2); - /** - * Update model based on command. - * - * @param command the command - */ - public void updateModel(Command command) { - setFatigue(command.getFatigue()); - setHealth(command.getHealth()); - setNourishment(command.getNourishment()); + controller.setCommand(new Command(Fatigue.SLEEPING, Health.HEALTHY, Nourishment.STARVING), 0); + controller.setCommand(new Command(Fatigue.ALERT, Health.HEALTHY, Nourishment.HUNGRY), 1); + + controller.updateView(giant1); + controller.updateView(giant2); } } ``` -Therefore, this example leverages the Service to Worker pattern to increase functionality cohesion and improve the business logic. +In the `main` method, we create two `GiantModel` instances, `giant1` and `giant2`, and two `Action` instances, `action1` and `action2`. We then create a `GiantView` instance and a `Dispatcher` instance. We add `action1` and `action2` to the `Dispatcher` and create a `GiantController` with the `Dispatcher`. We then update the view with `giant1` and `giant2`, set some commands, and update the view again. +This is a simple example of how the Service to Worker pattern can be implemented in a Java application. ## Class diagram -![alt text](./etc/service-to-worker.png "Service to Worker") + +![Service to Worker](./etc/service-to-worker.png "Service to Worker") ## Applicability -- For the business logic of web development, the responsibility of a dispatcher component may be to translate the logical name login into the resource name of an appropriate view, such as login.jsp, and dispatch to that view. To accomplish this translation, the dispatcher may access resources such as an XML configuration file that specifies the appropriate view to display. + +* Use when you need to separate the controller logic from the view to improve code maintainability and enable team members to work on different parts of the application independently. +* Suitable for Java web applications that utilize MVC architecture. +* Appropriate for scenarios requiring complex request processing before displaying a view. + +## Known Uses + +* Java-based web frameworks like Struts and Spring MVC. +* Enterprise web applications requiring a clean separation between presentation logic and business logic. + +## Consequences + +Benefits: + +* Enhances code maintainability by separating concerns. +* Facilitates team collaboration by decoupling the controller and view components. +* Simplifies the addition of new views and modifications to existing ones. + +Trade-offs: + +* Increases the complexity of the application structure. +* May introduce additional overhead due to the layered architecture. + +## Related Patterns + +* [Model-View-Controller (MVC)](https://java-design-patterns.com/patterns/model-view-controller/): Service to Worker is a specialized form of MVC, focusing on separating request handling and view management. +* [Front Controller](https://java-design-patterns.com/patterns/front-controller/): Often used in conjunction with Service to Worker to centralize request handling and routing. ## Credits -* [J2EE Design Patterns](https://www.oreilly.com/library/view/j2ee-design-patterns/0596004273/re05.html) -* [Core J2EE Patterns](http://corej2eepatterns.com/Patterns/ServiceToWorker.htm) + +* [Core J2EE Patterns: Best Practices and Design Strategies](https://amzn.to/4cAbDap) +* [Design Patterns: Elements of Reusable Object-Oriented Software](https://amzn.to/3w0pvKI) +* [J2EE Design Patterns](https://amzn.to/4dpzgmx) +* [Patterns of Enterprise Application Architecture](https://amzn.to/3WfKBPR) diff --git a/service-to-worker/src/main/java/com/iluwatar/servicetoworker/GiantController.java b/service-to-worker/src/main/java/com/iluwatar/servicetoworker/GiantController.java index 1b830b467..0be3ee5ad 100644 --- a/service-to-worker/src/main/java/com/iluwatar/servicetoworker/GiantController.java +++ b/service-to-worker/src/main/java/com/iluwatar/servicetoworker/GiantController.java @@ -24,8 +24,6 @@ */ 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.