Service to Worker J2EE

The system controls flow of execution and access to business data, from which it creates presentation content.

Note

The Service to Worker pattern, like the Dispatcher View pattern, describes a common combination of other patterns from the catalog. Both of these macro patterns describe the combination of a controller and dispatcher with views and helpers. While describing this common structure, they emphasize related but different usage patterns.

Problem

The problem is a combination of the problems solved by the Front Controller and View Helper patterns in the presentation tier. There is no centralized component for managing access control,content retrieval,or view management,and there is duplicate control code scattered throughout various views. Additionally, business logic and presentation formatting logic are intermingled within these views, making the system less flexible, less reusable,and generally less resilient to change.

Intermingling business logic with view processing also reduces modularity and provides a poor separation of roles among Web production and software development teams.

Forces

  • Authentication and authorization checks are completed per request.
  • Scriptlet code within views should be minimized.
  • Business logic should be encapsulated in components other than the view.
  • Control flow is relatively complex and based on values from dynamic content.
  • View management logic is relatively sophisticated, with multiple views potentially mapping to the same request.

Solution

Combine a controller and dispatcher with views and helpers (see “Front Controller” and “View Helper”)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.

Service to Worker describes the combination of the Front Controller and View Helper patterns with a dispatcher component.

While this pattern and the Dispatcher View pattern describe a similar structure, the two patterns suggest a different division of labor among the components. In Service to Worker, the controller and the dispatcher have more responsibilities.

Since the Service to Worker and Dispatcher View patterns represent a common combination of other patterns from the catalog,each warrants its own name to promote efficient communication among developers. Unlike the Service to Worker pattern, the Dispatcher View pattern suggests deferring content retrieval to the time of view processing.

In the Dispatcher View pattern, the dispatcher typically plays a limited to moderate role in view management. In the Service to Worker pattern, the dispatcher typically plays a moderate to large role in view management.

A limited role for the dispatcher occurs when no outside resources are utilized in order to choose the view. The information encapsulated in the request is sufficient to determine the view to dispatch the request. For example,
The sole responsibility of the dispatcher component in this case is to dispatch to the view login.jsp.

An example of the dispatcher playing a moderate role is the case where the client submits a request directly to a controller with a query parameter that describes an action to be completed:

The responsibility of the dispatcher component here is 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.

On the other hand, in the Service to Worker pattern, the dispatcher might be more sophisticated. The dispatcher may invoke a business service to determine the appropriate view to display.

The shared structure of Service to Worker and Dispatcher View consists of a controller working with a dispatcher, views, and helpers.

Structure

The class diagram in Figure represents the Service to Worker pattern.

Service to Worker class diagram

Service to Worker class diagram

Participants and Responsibilities

Figure shows the sequence diagram that represents the Service to Worker pattern.

Service to Worker sequence diagram

Service to Worker sequence diagram

As stated, Service to Worker and Dispatcher View represent a similar structure. The main difference is that Service to Worker describes architectures with more behavior “up front” in the controller and dispatcher, while Dispatcher View describes architectures with more behavior moved back to the time of view processing. Thus, the two patterns suggest a continuum, where behavior is either encapsulated closer to the front or moved farther back in the process flow.

Controller

The controller is typically the initial contact point for handling a request. It works with a dispatcher to complete view management and navigation. The controller manages authentication, authorization, content retrieval, validation, and other aspects of request handling. It delegates to helpers to complete portions of this work.

Dispatcher

A dispatcher is responsible for view management and navigation, managing the choice of the next view to present to the user and providing the mechanism for vectoring control to this resource.

A dispatcher can be encapsulated within a controller (see “Front Controller”) or it can be a separate component working in coordination with the controller. The dispatcher can provide static dispatching to the view or it may provide a more sophisticated dynamic dispatching mechanism.

The dispatcher uses the RequestDispatcher object(supported in the servlet specification), but it also typically encapsulates some additional processing. The more responsibilities that this component encapsulates,the more it fits into the Service to Worker pattern. Conversely, when the dispatcher plays a more limited role, it fits more closely into the Dispatcher View pattern.

View

A View represents and displays information to the client. The information that is used in a display is retrieved from a model. Helpers support views by encapsulating and adapting a model for use in a display.

Helper

A helper is responsible for helping a view or controller complete its processing. Thus, helpers have numerous responsibilities, including gathering data required by the view and storing this intermediate model, in which case the helper is sometimes referred to as a value bean. Additionally, helpers may adapt this data model for use by the view. Helpers can service requests for data from the view by simply providing access to the raw data or by formatting the data as Web content.

A view may work with any number of helpers, which are typically implemented as JavaBeans (JSP 1.0+) and custom tags (JSP 1.1+). Additionally, a helper may represent a Command object or a delegate (see “Business Delegate”).

ValueBean

A value bean is another name for a helper that is responsible for holding intermediate model state for use by a view. A typical case, as shown in the sequence diagram in Figure 12, has the business service returning a value bean in response to a request. In this case, ValueBean fulfills the role of a Value Object(see “Value Object”).

BusinessService

The business service is a role that is fulfilled by the service the client is seeking to access. Typically, the business service is accessed via a Business delegate. The business delegate's role is to provide control and protection for the business service(see the “Business Delegate”).

StrategiesServlet Front Strategy

See “Servlet Front Strategy”.

JSP Front Strategy

See “JSP Front Strategy”.

JSP View Strategy

See “JSP View Strategy”.

Servlet View Strategy

See “Servlet View Strategy”.

JavaBean Helper Strategy

See “JavaBean Helper Strategy”.

Custom Tag Helper Strategy

See “Custom Tag Helper Strategy”.

Dispatcher in Controller Strategy

See “Dispatcher in Controller Strategy”.

As stated, the Service to Worker and Dispatcher View patterns suggest a continuum, where behavior is encapsulated closer to the front or moved farther back in the process flow. Figure describes a scenario in which the controller is heavily loaded with upfront work, but the dispatcher functionality is minimal.

Folding the dispatcher into the controller

Folding the dispatcher into the controller

Transformer Helper Strategy

See “Transformer Helper Strategy”.

Consequences

  • Centralizes Control and Improves Modularity and Reuse
  • This pattern suggests providing a central place to handle system services and business logic across multiple requests. The controller manages business logic processing and request handling. Keep in mind, though, that as control centralizes, it is possible to introduce a single point of failure.The pattern also promotes cleaner application partitioning and encourages reuse. Common code is moved into a controller and reused per request and moved into helper components, to which controllers and views delegate. The improved modularity and reuse means less duplication, which typically means a more bug-free environment.
  • Improves Application Partitioning
  • Using helpers results in a cleaner separation of the view from the business processing in an application. Helpers, in the form of JavaBeans (JSP 1.0+) and Custom tags (JSP 1.1+), provide a place for business logic to be factored out of the JSP. If the business logic is left in a JSP, large projects result in cumbersome and unwieldy scriptlet code.
  • Improves Role Separation
  • Separating the formatting logic from the application business logic also reduces dependencies on the same resources among individuals fulfilling different roles. Without this separation, for example, a software developer would own code that is embedded within HTML markup, while a Web production team member would need to modify page layout and design components that are intermingled with business logic. Because neither individual fulfilling these roles is familiar with the implementation specifics of the other individual's work, it raises the likelihood of modifications accidentally introducing bugs into the system.

Sample Code

The following sample code shows an implementation of the Service to Worker pattern, using a controller servlet, a command helper, a dispatcher component, and a view. The implementation includes the Servlet Front Strategy, Command and Controller Strategy, JSP View Strategy, and JavaBean Helper Strategy. A very basic composite view is used as well. A screen shot of the resulting display is shown in Figure.

Service to Worker sample screen shot

Service to Worker sample screen shot

Example shows the controller servlet, which delegates to a Command object(Command and Controller Strategy) to complete the control processing. The Command object is retrieved via a factory invocation, which returns the generic Command type, an interface shown in Example. The sample code uses a LogManager to log messages. The screen shots in Figure and Figure show these messages displayed at the bottom of the page, for the purposes of this example.

Example Controller Servlet with Command and Controller Strategy

public class Controller extends HttpServlet {
/** Processes requests for both HTTP
* <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest
request, HttpServletResponse response)
throws ServletException, java.io.IOException {
String next;
try {
// Log pattern info
LogManager.recordStrategy(request,
"Service To Worker",
" ServletFront Strategy;" +
" JSPView Strategy; JavaBean helper Strategy");
LogManager.logMessage(request, getSignature(),
"Process incoming request. ");
// Use a helper object to gather parameter
// specific information.
RequestHelper helper = new
RequestHelper(request,response);
LogManager.logMessage(request, getSignature(),
"Getting command object helper");
// Get command object helper
Command command = helper.getCommand();
// delegate processing to the command object,
// passing request and response objects along
next = command.execute(helper);
/** If the above command returns a value, we
* will dispatch from the controller. In this
* example, though, the command will use a
* separate dispatcher component to choose a
* view and dispatch to that view. The command
* object delegates to this dispatcher
* component in its execute method, above, and
* control should not return to this point **/
}
catch (Exception e) {
LogManager.logMessage(
"EmployeeController(CommandStrategy)",
e.getMessage() );
/** ApplicationResources provides a simple API
* for retrieving constants and other
* preconfigured values**/
next = ApplicationResources.getInstance().
getErrorPage(e);
}
dispatch(request, response, next);
}
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
processRequest(request, response);
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, java.io.IOException {
processRequest(request, response);
}
/** Returns a short description of the servlet. */
public String getServletInfo() {
return getSignature();
}
/** dispatcher method */
protected void dispatch(HttpServletRequest request,
HttpServletResponse response,
String page) throws javax.servlet.ServletException,
java.io.IOException {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher(page);
dispatcher.forward(request, response);
}
public void init(ServletConfig config) throws
servletException {
super.init(config);
}
public void destroy() { }
private String getSignature() {
return "ServiceToWorker--Controller";
}
}

Example Command Interface

public interface Command {
public String execute(RequestHelper helper) throws
javax.servlet.ServletException, java.io.IOException;
}

Dispatcher View sample screen shot
Dispatcher View sample screen shot

Each Command Object helper implements this generic interface, which is an example of the GoF Command pattern. The Command object is an instance of the ViewAccountDetails class, which is shown in Example. The command instance delegates to an AccountingAdapter to make an invocation to the business tier via business delegate. The adapter class is shown in Example. It uses a separate dispatcher component to determine the next view to which control should be dispatched and to actually dispatch to this view.

Example ViewAccountDetailsCommand

public class ViewAccountDetailsCommand implements
Command {
public ViewAccountDetailsCommand() { }
// view account details operation
public String execute(RequestHelper helper)
throws javax.servlet.ServletException,
java.io.IOException {
/** This will tell the user that a system error
* has occured and will typically not be seen. It
* should be stored in a resource file **/
String systemerror =
"/jspdefaultprocessingerror.jsp";
LogManager.logMessage(helper.getRequest(),
"ViewAccountDetailsCommand",
"Get Account Details from an adapter object");
/** Use an adapter to retrieve data from business
* service, and store it in a request attribute.
* Note: Object creation could be avoided via
* factory, but for example purposes object
* instantiation is shown **/
AccountingAdapter adapter = new
AccountingAdapter();
adapter.setAccountInfo(helper);
LogManager.logMessage(helper.getRequest(),
"ViewAccountDetailsCommand", "processing complete");
/** Note: Object creation could be avoided via
* factory, but for example purposes object
* instantiation is shown**/
Dispatcher dispatcher = new Dispatcher();
dispatcher.dispatch(helper);
/** This return string will not be sent in a
* normal execution of this scenario, because
* control is forwarded to another resource
* before reaching this point. Some commands do
* return a String, though, so the return value
* is included for correctness. **/
return systemerror;
}
}

Example AccountingAdapter

public class AccountingAdapter {
public void setAccountInfo(
RequestHelper requestHelper) {
LogManager.logMessage(
requestHelper.getRequest(),
"Retrieving data from business tier");
// retrieve data from business tier via
// delegate. Omit try/catch block for brevity.
AccountDelegate delegate =
new AccountDelegate();
AccountVO account =
delegate.getAccount(
requestHelper.getCustomerId(),
requestHelper.getAccountKey());
LogManager.logMessage(
requestHelper.getRequest(),
"Store account value object in request attribute");
// transport data using request object
requestHelper.getRequest().setAttribute(
"account", account);
}
}

The invocation on the business service via the delegate yields an Account Value object, which the adapter stores in a request attribute for use by the view. Example shows accountdetails.jsp, the JSP to which the request is dispatched. The Value object is imported via the standard <jsp:useBean> tag and its properties accessed with the standard <jsp:getProperty> tag. Also, the view uses a very simple composite strategy, doing a translation-time inclusion of the trace.jsp subview, which is responsible for displaying log information on the display solely for example purposes.

Example View - accountdetails.jsp

<html>
<head><title>AccountDetails</title></head>
<body>
<jsp:useBean id="account" scope="request"
class="corepatterns.util.AccountVO" />
<h2><center> Account Detail for <jsp:getProperty
name="account" property="owner" />
</h2> <br><br>
<table border=3>
<tr>
<td>
Account Number :
</td>
<td>
<jsp:getProperty name="account" property="number" />
</td>
</tr>
<tr>
<td>
Account Type:
</td>
<td>
<jsp:getProperty name="account" property="type" />
</td>
</tr>
<tr>
<td>
Account Balance:
</td>
<td>
<jsp:getProperty name="account" property="balance" />
</td>
</tr>
<tr>
<td>
OverDraft Limit:
</td>
<td>
<jsp:getProperty name="account"
property="overdraftLimit" />
</td>
</tr>
</table>
<br>
<br>
</center>
<%@ include file="/jsp/trace.jsp" %>
</body>
</html>

Related Patterns

  • Front Controller and View Helper
  • The Service to Worker pattern is the result of combining the View Helper pattern with a dispatcher, in coordination with the Front Controller pattern.
  • Dispatcher View
  • The Dispatcher View pattern is another name for the combination of the Front Controller pattern with a dispatcher,and the View Helper pattern. The Service to Worker and the Dispatcher View patterns are identical with respect to the components involved, but differ in the division of labor among those components. The Dispatcher View pattern suggests deferring content retrieval to the time of view processing. Also, the dispatcher plays a more limited role in view management, as the choice of view is typically already included in the request.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

J2EE Topics