E++: A pattern language for J2EE applications, Part 2

Weave the design patterns together

A good framework represents at least half of a project as it decomposes an application into manageable components with consistent and well-established methodology. After kicking off a J2EE development effort, you need a framework to make it succeed. E++ is a pattern language for developing a MREPICS framework on the J2EE platform. In Part 1 of this series, I explained E++'s applicability, design principles, and architecture patterns.

Read the whole "E++: A pattern language for J2EE applications" series:

In this article, the second of two, I continue the progress made in Part 1 by detailing the patterns most important for a successful E++ implementation. As outlined in Part 1, to design the application as a whole, you should follow the E++ tree (Figure 1), from root to branches to leaves. As such, you'll find it useful to refer to the E++ tree as you work through the design patterns detailed below.

Figure 1. The E++ tree

Due to space considerations, it is impossible to detail all of the E++ implementation patterns here; I'll stick to the major patterns and their uses. For more complete information and the related patterns, see the Resources section below. Continuing the practice from Part 1, for each major pattern I will detail:

  • The pattern name
  • The context in which the pattern applies
  • The design problem raised by the context
  • The conflicting forces that must be resolved
  • The solution offered by the pattern

So, let's get to the patterns!

Pattern name: Application Mediator

Context

The E++ tree starts with Application Mediator, an object that sits between the client and the application to handle all human or nonhuman inputs. As such, it is the single entry point to the application. Such an arrangement is suggested by the Layered Architecture pattern described in Part 1 of this series. On real-world application servers, you achieve this with the configuring<servlet-name>webTierEntryPoint</servlet-name> attribute of a web.xml file.

The problem

What functionality should the Application Mediator possess so that it mediates reusable pieces together?

The forces

You should construct the E++ generic J2EE application framework such that it does not depend on any specific user requirements or actions. As a framework for large-scale enterprise applications, the Application Mediator should address every aspect of the application, such as JSP presentation layout, application models, security, and internationalization.

The solution

The Application Mediator should function like an organization's front desk: it should comprehensively refer to a specific manager to handle a specific set of tasks. As such, the mediator object encapsulates all interconnections, acts as the communications hub, and controls and coordinates its clients' interactions. Further, it delegates suitable user requirements to specific manager objects.

The E++ Application Mediator interacts with the following manager objects:

  • The ComponentManager loads the component module information at runtime through an XML interface. It helps decouple the framework from domain-specific programming. The ModelManager manager uses the supplied information.
  • The JSP Layout manager selects application presentations; it comprises JSP Template, JSP Page, and JSP Tag.
  • The Event Processor, a help object, changes application models at all tiers according user requests.
  • The Locale Manager handles language localization.
  • The Security Manager operates the application's security realm.
  • The ModelManager handles model synchronization of different tiers and serves as a gateway of the model retrieval from the Web tier.

Each of these manager objects works with general human or nonhuman clients (XML inputs). Each is cached in ServletContext as soon as it instantiates at startup time, with the exception of ModelManager. Since ModelManager keeps a specific session's EJB registry for fast access, it is cached in HttpSession.

In a simple example, let's examine the characteristics of an Application Mediator pattern:

  • It's designed as a HttpServlet.
  • All client inputs (HttpRequests) go through the servlet's doGet() or doPost() methods.
  • It creates or retrieves a ComponentManager JavaBean that loads and caches customized module information.
  • It creates or retrieves a JSP Layout Manager JavaBean that gets the next screen, if required
  • It creates or retrieves an Event Processor JavaBean that passes the requests. The processor will process all user requests to change application EJBs and other related functionality
  • It creates or retrieves a ModelManager JavaBean that handles synchronization of different tiers and serves as a gateway of model retrieval from the Web tier.
  • It creates or retrieves a LocaleManager JavaBean that determines the specific language locale for the request. Remember, 2-byte Java character encoding just provides internationalization and localization potential.
  • It creates or retrieves a SecurityManager JavaBean that handles the security realm.

Figure 2 shows the Application Mediator pattern's UML diagram. A general reminder: all the managers should implement a serializable interface that can be replicated in a failover or cluster environment.

Figure 2. The Application Mediator

Pattern name: Component Manager

Context

You need to design the Component Manager.

The problem

The Component Manager should not hardcode application-specific Java objects and EJBs; if it does, the E++ framework will not be directly reusable for any other applications. With this in mind, how do you decouple the Component Manager from the customized module information, and, at the same time, be able to use them?

The forces

The Component Manager must load application-specific information, such as an EJB URL, at runtime; it should not compromise application performance.

The solution

Use an XML file to describe your module information. The Component Manager has an XML parser to load the file at startup time; as it will be cached in ServletContext for general use, you will not experience any performance degradation. This design allows E++ to work with any import module -- but not depend on them. Figure 3 shows the Component Manager pattern's UML diagram.

Figure 3. The Component Manager

Pattern name: JSP Layout Manager

Context

You like the layout managers found in the Java Foundation Classes (JFC), as they help assemble visual components together. Based on the JSP Page and Tag, you want to construct a JSP Layout Manager for your Web application to conduct similar tasks.

The problem

For a browser-based application, you do not have generic GUI components. How do you come up with a mechanism to consistently present your application layout?

The forces

Because an application's layout will change over time, it's not smart to quickly glue parts together on the fly. Rather, design the layout handling codes to be understandable, maintainable, and reusable.

The solution

The solution stems from the Template Method design pattern, which sets up an outline of a composition object, leaving details to a specific implementation. This approach proves particularly useful for separating the variant and the invariant context, thus minimizing the code size. Each page consists of four or more portions: banner, index, body, and footer. Of the four, in general, only the body changes page by page.

The variant is placed in the abstract class (template), allowing any subclasses that inherit it to override the abstract methods and implement the specifics needed in that context. (Many ways exist for you to implement this design concept. Indeed, you'll find a detailed JSP template implementation in Resources.)

Pattern name: Event

Context

You need to design the Event Processor to handle incoming HttpRequests to establish a generic request-control infrastructure.

The problem

For synchronized communication, in Java you can wire components through either general method invocations or events. How do you choose a discipline for the interactions so that the design and implementation will be structured, understood, and reused?

The forces

So far, there are two Java event models:

  • The Java 1.0.2 event model, known as the inheritance model, allows an event to be handled only by the component that originated the event, or by one of the containers that contained the originating component. Many consider the inheritance model one of Java's early design flaws.
  • The Java 1.1 delegation event model (extended in Java 2) follows a publish-and-subscribe metaphor; events are received by subscription only. If a component shows no interest in an event type, then events of that type will not be propagated to it.

The solution

The Java delegation event model is our solution here. This model not only allows users to connect and manipulate JavaBeans programmatically or visually using a bean builder; it also proves powerful for the sort of nonvisual object wiring that our case requires. Objects communicate with each other via event notifier(Model Manager). The event notification is type safe, instance based, synchronous, and multicasting. Further, it is restricted to a single process. For every event generated from HttpRequest, you define one corresponding EventListener interface so that Web Model JavaBeans can be associated with the listener by implementing the interface. The Event notifier(Model Manager), an event service, notifies the listeners. The delegation model is ideal for large application design, since it provides flexibility and consistent coordination. The UML diagram of the Event pattern is shown in Figure 4, in which the EPPEvent extends java.util.EventObject.

Figure 4. The Event pattern

Pattern name: Web Model JavaBean

Context

With Event as your basic processing infrastructure, you need to design your listener objects -- a Java Bean representing the application model at the Web tier.

The problem

Given the J2EE n-tier architecture's benefits, because any EJB call goes through the RMI protocol, performance could be an issue. If you use only JSPs or servlets without EJBs -- a so-called Web-centric application, in other words -- you have Web-tier JavaBeans encapsulating your business model. In a n-tier architecture, your real application models are EJBs instead, so any model change or update information has to be forwarded to the Web tier. So you need to design application model JavaBeans at the Web tier. If you do not have these peers, you have to access the EJBs whenever you need model information -- a performance overkill.

The forces

The Web Model JavaBean design must:

  1. Contain application model information
  2. Be updated following user inputs

The solution

As our solution, we turn to the Event pattern. Design these Web-tier JavaBeans to implement the same model interface as the EJB. Moreover, depending on your business logic, let these JavaBeans associate with one or more interested events by implementing their listeners. Each time EJBs are created or updated, the event notifier(Model Manager) automatically updates the JavaBeans. That way you can directly retrieve model information from these JavaBeans. Figure 5 shows the UML diagram. (It is not necessary to have such a notification mechanism for a Web-centric application.)

Figure 5. Web-tier Model JavaBeans and Event Processor

Pattern name: Event Processor

Context

You need to process incoming requests to change or update the application model based on the Event and Web Model JavaBean patterns, leading you into the Event Processor design.

The problem

The processor, in principle, merely changes related application models and updates their Web peers. With that in mind, how do you fine-grain the processor so that it will be more robust and reusable?

The forces

Because the Event Processor pattern proves crucial to the whole architecture's reusability, it must be designed in a generic fashion such that all individual functions easily plug in. On the other hand, it should carry

a so-called smart caching mechanism to improve performance -- rather important for n-tier distributed systems.

To forward requests to the EJB tier, you may process the users' requests to if-else statements. However, it's problematic to create an ever-increasing list of if-else statements to dispatch requests to individual handlers. As indicated in Part 1, one of the desired MREPLICS features is inversion of control, which allows the framework (rather than developers) to determine which set of application-specific methods to invoke in response to external events.

The solution

Whenever we speak of a generic processor, we usually mean the Command pattern, as is our case here. The Event Processor uses the Event pattern and Web-tier model JavaBeans as its processing foundation, while the Model Manager employs the Command pattern to serve the notification. Within the Event pattern, the whole event processing proceeds as follows:

  1. Generates Event based on the incoming HttpRequest
  2. Sends the Event to EJB Facade (detailed next) for EJB model processing
  3. Creates the Web Model JavaBean to mirror the EJB Model; it registers interested event listeners for update notification
  4. Uses the Model Manager object to perform the notification process while the manager executes command processing

You'll find the Event Processor's UML diagram in Figure 4. For information about the Model Manager or other patterns, please refer to Resources.

Pattern name: EJB Facade

Context

1 2 3 Page 1
Page 1 of 3