CONTENTS | PREV | NEXT | INDEX J2EE BluePrints



3.6 Designing for Multiple Types of Client

We have discussed several approaches to building clients for enterprise applications and how the choice of a client influences service implementation. Often, an enterprise application will have more than one type of client accessing its services.

A banking application might expose a simple Web interface for account-holders to view account balances, as well as provide a richer interface through a stand-alone client that customers can install on their desktop computers. In this example both clients have similar functionality although they use different mechanisms to present their interface to the user. A banking application might also provide a stand-alone client administration interface.

When designing an enterprise application, you should pay attention to handling multiple types of client interactions. The overall application design should support each new type of client with minimal additional effort. It should also avoid duplicating code either by sharing the application objects among multiple clients, or by reusing them through encapsulation, delegation, or inheritance.

This section discusses approaches to designing enterprise applications that can support multiple types of clients.

Application data and business rules are independent of the clients that access the application, making it desirable to design these objects to be shared across all the different clients of the application. When different types of clients present the same functionality through different interfaces, it is useful to share objects that encapsulate this functionality or client behavior.

The distinction between objects that can be shared or reused, and objects that need to be implemented separately for each type of client can be discussed in terms of the MVC architecture. The follow sections consider the issues that arise when designing the model, view, and controller to support multiple types of clients.


3.6.1 Model

The model is a software abstraction of the application data and the business rules that apply for changing this data. The model can be shared across all clients of the application. It should be consistent regardless of the type of client accessing the data. If the model faithfully captures all possible ways that data can be changed, there is no need to implement different model classes, or develop specific model objects for each client type.

When each type of client represents a different level of authorization to the system, it is sometimes desirable to wrap the access to the underlying model into security mediator objects. This allows the model to be shared across all clients, while access control restrictions can be enforced more flexibly. Security mediator objects are described in Section 9.3.6.

In situations where the models that two clients of the application work with are independent of one another, the application can be thought of as being comprised of multiple subapplications. In this case the programming model would be applied to each of these subapplications independently.


3.6.2 View

A view renders the contents of a model. It accesses data from the model and specifies how that data should be presented. The view changes most significantly across clients. This makes it hard to share entire view implementations. However, some code sharing can still be effected at a finer grained level. This is especially true when clients use the same medium for presentation, but provide different functionality.

For example, the sample application could provide a Web-based shopping interface and a Web-based administration interface. Although very different in functionality, they both are Web based. If a showOrder custom JSP tag were used to render details of a particular order to HTML, the same tag could be used by both the shopping and the administration clients.


3.6.3 Controller

A controller defines application behavior; it interprets user gestures and maps them into actions to be performed by the model. Each client that exposes different functionality requires a separate controller. For example, the sample application would need separate controllers for shopping and administration clients. There is always some opportunity to reuse code that is part of the application controller framework; however, this is independent of the type of clients accessing the application.

However, multiple clients that expose similar or identical functionality should be able to share the controller responsible for the functionality. If the clients provide only slightly different functionality, it should still be possible to reuse the controller implementation by using a single class to implement the common behavior and using subclasses to implement the custom behavior. For example, the banking application described earlier has a Web-based interface as well as a stand-alone desktop client. The difference between the clients is how they present the interface--the view. Therefore they can share the same controller.

Because the controller interacts directly with the view it is not completely insulated from changes in the view implementation. For example, strongly typed references to view objects in the controller make it difficult to redeploy. In order to design the controller to allow a large portion of its implementation to be shared, we need to examine the interactions between the view and the controller and find ways to minimize the effect of those interactions on the controller. The interactions are:

3.6.3.1 Interpreting User Gestures

The controller accepts user gestures from the view. These depend on the medium that the view uses to present the user interface. For example, in a JFC application, the user gestures could be "button pressed" events or "mouse moved" events, and so on. In a Web interface, the user gestures appear as GET or POST requests for URLs of the application. In a messaging environment, the user gestures take the form of asynchronous messages.

To keep the controller as reusable as possible, the controller must translate these user gestures as soon as possible and turn them into business events--uniform, view-neutral representations of the actions requested by the user.

The sample application uses RequestToEventTranslator for this purpose. This object takes an HttpServletRequest from the view--a browser in this case--and translates it into an EStoreEvent business event. RequestToEventTranslator is discussed in Section 10.6.3. The rest of the controller implementation deals only with EStoreEvent and can be reused for different implementations of the view. If we wanted to implement a JFC-based client for the sample application, we could just add another translator that translates JFC events into business events.

Code Example 3.1 shows how RequestToEventTranslator takes a request and translates it into a business event. An object that implements ShoppingClientControllerInterface, which provides the core of the controller responsibilities, invoked using an EStoreEvent, does not need to change when the client changes.


public class RequestProcessor {
	ShoppingClientControllerInterface scc;
	RequestToEventTranslator eventTranslator;

	public void processRequest(HttpServletRequest req) {
		...
		// translate view specific event into EStoreEvent
		EStoreEvent event = eventTranslator.processRequest(req);
		if (event != null) {
			// invoke the controller with EStoreEvent, instead of 
			// using the view specific HttpServletRequest 
			Collection updatedModelList = scc.handleEvent(event);
			mm.notifyListeners(updatedModelList);
		}
		...
	}
}
Code Example 3.1 Translating View-Dependent Gestures into View-Neutral Business Events
3.6.3.2 Selecting the View

The controller selects which view to display. These depend on the medium that the view uses to present the user interface. For example, in a JFC application, the user views are composed of Swing components such as panels, lists, tables, and so on. In a Web interface, the views are HTML pages that are rendered by a browser.

To keep the controller as reusable as possible the controller needs to express views in a technology-neutral fashion and translate them to technology-specific renditions as late as possible. This would require a layered view selection component that uses objects to represent views (analogous to the business events in the previous section) which are forwarded to specific types of view generators. For example, a product list view would contain all the data needed to represent a list of products. This object could be passed to a view generator, which would render the data in a specific user interface medium. Note that depending on the medium, the view generator may reside on the server (HTML) or on the client (JFC).

3.6.3.3 Example: The Sample Application Controller

The sample applications controller is in two parts: the EJB controller, which interacts with enterprise beans and a controller proxy, which interacts with views. In the current release, the proxy is monolithic and specific to Web clients.

If another type of shopping client interface were required, the EJB controller could be shared without modification. However, the proxy portion of the controller would have to be rearchitected to support more than one type of view technology. For example, a JFC-based view selection component would need to register event listeners when the view is created. These listeners would then post or propagate the events to the client portion of the controller.



CONTENTS | PREV | NEXT | INDEX
Copyright © 2001 Sun Microsystems, Inc. All Rights Reserved.