E++: A pattern language for J2EE applications, Part 1
Build better J2EE applications with a high-level pattern language
Your company decides to build or migrate from existing two-tier applications to an n-tier J2EE solution. The targeted application needs to have characteristics of modularity, reusability, extensibility, portability, inversion of control, consistence, and scalability (MREPICS) (see the sidebar for more on MREPICS principles). Your task: efficiently build a high-quality application leveraging standard J2EE components.
Read the whole “E++: A Pattern Language for J2EE Applications” series:
- Part 1: Build better J2EE applications with a high-level pattern language
- Part 2: Weave the design patterns together
Rather than design all the pieces from scratch, you wisely desire to leverage the well-established Gang of Four (GOF) design patterns. The challenge: you must select among two dozen GOF design patterns under a functional taxonomy (creational, structural, and so on) and apply them to J2EE components. Sound tough? In this article, you’ll learn how to make the process easier with the E++ language.
E++ makes design patterns friendlier to designers by effectively coordinating patterns in real projects. Different from the GOF’s taxonomic approach, the E++ pattern language contains not only design patterns, but also architectural patterns that provide frameworks of the whole application for design patterns. Moreover, it describes the rules for design patterns working together to construct a high-quality J2EE framework. In short, E++ shows how to architect a real-world J2EE project using closely related design patterns.
In the sections below, we will first establish the foundation of the language, then, beginning with the Layered Architecture pattern, describe the whys and how-tos of decomposing the system and partitioning functionalities in different subsystems. Next, the MVC architecture pattern provides a set of patterns for laying out the architecture of an interactive B2C scenario. Further, the REAI (Rule Engine-Based Enterprise Integration) architecture pattern depicts how the application integrates with backend remote systems. A few deployment patterns are also addressed to help deploy applications in production.
Pattern language: A better approach
The first systematic attempt to describe patterns was made by the ancient Greeks, resulting in Aristotelian prepositional logic. Indeed, the heart of today’s Pentium processor comprises a complex of prepositional logic patterns, etched into silicon.
The current design pattern movement draws on the work of the architect Christopher Alexander. In A Pattern Language, he suggested that each design pattern, “… is a rule, which establishes a relationship between a context, a system of forces which arises in that context, and a configuration which allows these forces to resolve themselves in that context” (Christopher Alexander, 1977). In an object-oriented programming environment, a pattern indicates a cluster of cooperating objects linked by certain relationships found repeated in a design. Application design is tremendously hard work, and with design patterns existing in isolation and without correlation, it is always a struggle to integrate the patterns into an actual design project.
In order that the knowledge represented by design patterns can be effectively utilized and become part of the collective design knowledge, the patterns have to be structured. The whole set of patterns for a specific application domain, together with their structuring principles, becomes a high-level language and a design method for the domain that accompanies the software life cycle.
For its part, the GOF taxonomy includes categories such as creational and structural, with the patterns presented under these categories. This structure has been followed by most current pattern presentations.
In contrast to the GOF taxonomical approach, we’ll look at patterns with a pattern language for creating a J2EE framework with the hope that a pattern approach would be more useful for designers and more understandable for developers.
Again, just as a framework is not a collection of classes, a pattern language is not just a loose collection of patterns. The pattern language provides an organization of the decision sequences that generated the framework design, and these must be understood in their proper context by the developer when making new decisions regarding which classes and collaboration structures to add to the framework.
With that in mind, the E++ pattern language extends previous design pattern work and presents, within the J2EE application context, ideas closer to Alexander’s idea of a pattern language as a whole design method.
The electronic commerce problem
In this series, we’ll target an application domain that is a Web-based, large-scale B2C and B2B integration framework implemented in J2EE. We’ll employ the following business case to illustrate the E++ pattern language.
Telecommunication Service Provider, Inc. (TSP) distributes telecom services to subscribers and resellers. This fictitious company requires a Web-enabled business application to support order creation, provisioning, fulfillment, deletion of orders, and billing information, as seen in Figure 1.
Along with providing interactive applications to handle its orders and billing information, TSP wants to integrate the Web application with backend services to automate processes of order provisioning, fulfillment, and banking services to enhance the application’s efficiency. The application needs to access remote services through HTTP/HTTPS, CORBA, and RMI protocols. XML should be supported in the process. As business rules change frequently, the company should be able to modify or update the application at runtime.
An application provider, Telecom Soft Co. (TS), will develop the application for TSP. The application will also be used as the basis for a product sold by TS to other businesses within the telecom distribution industry. TS’s goal: create an application that is highly flexible, portable, and easily customizable for other clients. Under such conditions, the application framework must comply with object-oriented design principles and patterns to generate a MREPICS solution.
We’ll learn how to solve this problem using the E++ pattern language in the following sections.
The pattern language in detail and practice
The E++ pattern language, as depicted in Figure 2, follows a treelike topology. Each circle denotes a pattern, with arrows representing the relationships among patterns. Architectural patterns are green-colored to indicate the beginning of the language. With E++, building a J2EE framework becomes as easy as following the tree network from the root to the leaves.
The Layered Architecture discusses the whys and how-tos of partitioning application functionality into tiers; it is a general guideline for arranging large-scale applications. In light of the Layered Architecture, the MVC architecture shows that classes and objects of the B2C portion can be effectively organized into three major functionality subsystems: model, view, and control. On the B2B side, the REAI architectural and related design patterns deal with distributed integrations. Before delving into the language details, let us work through the language to show how the patterns work together.
B2C flow
In our scenario, a customer accesses the TSP Website using a Web browser, hits the items of interest, and generates HTTP requests to the Web server, which directs all the requests to the Application Mediator, with the mediator working as a single entry point to the application. To respond to the requests, the mediator dispatches the customer’s requests to the JSP Template pattern, which serves as a layout manager and produces all the required JSP/HTML files for the customer’s browsing. As the name suggests, the Template Method combines with JSP Tags and JSP Pages to handle the presentation scenario. Following that, it independently forwards the customer’s requests to the Event Processor pattern.
If the requests require changing application models, such as ordering, accounting, and billing HTTP requests, the processor interprets the requests to Java events using the Event pattern and then delegates the corresponding tasks to the EJB tier through the EJB Facade by sending these events. The EJB Facade pattern acts as single entry point to the EJBs, as well as controls and synchronizes concurrent access to the EJB layer. Note that the Event pattern is essentially the Java delegation event model, which allows indirect method invocations. The Event pattern has been widely used as a better application control alternative in Java 1.1 and later versions.
The EJB Facade forwards all the events to the EJB Controller, a stateful session EJB representing the customer at the EJB tier. The EJB Controller simplifies the processing and leverages the State Machine pattern to change application state. The machine then uses the Command pattern to fulfill the event processing and create or change the Model EJB or Session EJB Facade. The Model EJB encapsulates business logic, while the Session EJB Facade offers an effective way, in terms of network traffic, to update database tables. The Value Object pattern improves response time to access coarse-grained data, while the Flyweight Object pattern reduces the number of objects in memory. The Data Access Strategy and Connection Factory patterns access relational databases in a flexible and extensible way. Finally, the Data Iterator pattern provides a practical way to fetch large chucks of read-only data. Through these patterns, the application model at the EJB tier is changed or updated.
The Web tier needs to know these model changes and be updated. To accomplish this, Web Model JavaBeans, which serve as mirrors of these Model EJBs, are registered as event listeners so that they are notified as soon as the Model EJB changes. The Event Processor employs the Command pattern to update the JavaBeans, which feeds updated data to JSP pages for customer browsing. JSP pages, one of the standard J2EE Web components for application presentation, retrieves data either directly from the mirror JavaBeans or indirectly through JSP tags in case data looping is necessary.
Note that for read-only access, such as catalog browsing, JSP should access the database through Web JavaBeans and bypass EJBs.
B2B flow
Because some of the customer’s events require access to backend remote services, we also must focus on the B2B scenario. The REAI (Rule Engine-based Enterprise Application Integration) architecture pattern acts as the framework for conducting B2B integration services.
The Scheduler pattern initiates B2B requests and executes each specific task as a single thread. The thread uses the Integration Rule Engine to figure out the correct XML schema and backend connectivity. The engine, a stateless EJB, leverages the XML DTD design pattern to design its XML schema. Meanwhile, the XML Transformer pattern transfers one XML schema to another so that the sent XML can be understood by receivers. The engine uses the Security pattern to secure the data transportation if required. Integration business rules are scripts residing outside the rule engine, so they can be changed at runtime by nonprogrammers. The engine then takes action using the Dispatcher pattern to get remote services. The Dispatcher pattern uses the Proxy Adapter, Remote Facade Wrapper, and JMS patterns to establish the actual connectivity. Lastly, the Prototype Reality Bridge pattern describes a seamless development evolution from simulation to reality.
Moving on, the Migration pattern demonstrates how Web-centric applications can be moved to an E++-recommended architecture. The Security pattern addresses security related to Internet-based enterprise solutions including confidentiality, integrity, authentication, and nonrepudiation. The Cluster pattern provides rules about how to deploy the framework in production.
Now let’s drill down to the detailed patterns starting with the three architectural patterns: Layered Architecture, MVC, and REAI.
In order to describe the patterns, I’ll detail each component within a group with:
- 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
The Architecture pattern
The Architecture pattern expresses a fundamental structure-organization schema for software systems. It provides a set of predefined subsystems, specifies their relationships, and includes rules and guidelines for organizing the relationships among them.
Pattern name: Layered Architecture
Context
You are designing the TSP J2EE application.
Problem
How do you arrange application functionality or responsibility among distributed processing contexts to maximize MREPLICS features?
Forces
Traditionally, developers draw a UI with an interface-building tool and then write blocks of code that execute application actions in response to user input. Many design methodologies emphasize starting with the UI, which all too often solidifies into a final system design. The result: a program organized around UI elements and user actions on those elements, with persistent data manipulation, application functionality, and display code completely intertwined. The code typically ends up with numerous if-else statements.
Code structured in such a fashion can succeed for small, single-user systems whose functionality requirements change slowly over time. However, such a structure proves inadequate for large, long-term, distributed projects because it exhibits:
- Poor modularity: Due to monolithic fashion and excess interdependency, it is much more difficult to achieve modular systems. Indeed, a change to the code anywhere produces side effects everywhere. Unit tests prove difficult too.
- Poor reusability: Your code will be less reusable because each component depends on many other components. Dependencies among components make the components less usable in other contexts.
- Poor extensibility: When new functional requirements appear, it’s difficult to find the code that needs to be changed or extended. Moreover, new interfaces must be developed from scratch, since the control logic is buried in the code.
- Poor consistency: Sophisticated applications often require multiple ways to view and manipulate the same data. The result is often similar data calculated or accessed in different ways, resulting in display-value inconsistencies. Even if the displayed data are correct, any change to the data display must be updated in multiple places, opening the door for flaws.
- Poor scalability: It is difficult to increase workloads — the solution simply doesn’t scale.
- Not event-driven: A J2EE application differs greatly from transitional applications: it is networked and event-driven by nature.
- Poor portability: Porting the application can become much more difficult. If business-logic code accesses a particular vendor’s product (a database, for example) from everywhere in the application, platform moves become next to impossible.
The solution
To solve the problem, put your application into different layers, a move considered to be a better practice since it separates conceptually different issues.
From an architectural point of view, partition your system into a number of layers and place them on top of one another such that services of layer n + 1 consist mostly of the services provided by layer n or a combination of sublayers. This moves us significantly toward a MREPLICS solution because, within the same layer, all the components work at the same level of abstraction or the same functionality.
As shown in Figure 3, we need to have a virtual functionality provide_Service()
method. Figure 3, section (a) illustrates how it looks when done in a monolithic programming fashion; components engage in cross talk whenever necessary at coding time. It would be difficult to extend the code to provide more functionality, in particular if the programmer responsible were no longer with the company. In contrast, Figure 3, section (b) illustrates the correct way to handle the situation: layer the system and allow components to talk to different layers through a unified interface.
Although there are numerous benefits and advantages of a layered architecture, including more freedom and increased flexibility, it does leave designers with more responsibilities. Indeed, they themselves have to design interfaces between layers and ensure application consistency and availability. Fortunately E++ does these tasks for us.
Pattern name: MVC architecture
Context
After adopting the Layered Architecture, we want to determine the number of layers needed, as well as establish the control and communication mechanism of the inter- and intra-layers such that the architecture is simple, more MREPICS-compatible, and maintainable over the long term.
The problem
How do we determine the most appropriate number of layers to have a simple but effective control and communication mechanism?
The forces
Compared with traditional programs, a Web-based J2EE program must offer a UI for various users with different roles. The UI is also prone to change, so a UI tightly interwoven via the application’s other parts will prove expensive and error-prone.
At the same time, a synchronization issue exists between the front and back layers; application models must be consistent across all layers. We need a more dedicated inter- and intra-layer control and communication mechanism.
The solution
As shown in Figure 4, MVC represents the solution to our problem. The pattern requires that each of these — model, view, and control — reside in different object clusters.
The model contains the functional core of the application. It encapsulates the appropriate data and performs application-specific processing. The model also provides functions to access its data used by view components to acquire the data to be displayed.
View components present information to the user. Different views present the model’s information in different ways. Each view is involved in an update procedure activated by the event model. When the update procedure is called, a view retrieves the current data values to be displayed from the model, and puts them on the screen.
The controller is function-based. In our case study there will be three control models for three different functionalities: B2C, B2B, and TSP administration. The control module is mapped into a composition of the component set. It is the only link between the model and the view.
Applying the MVC architecture to the standard J2EE platform, we have the fine-grain four tiers as shown in Figure 4, section (b):
- EJB Model — EJB encapsulating business logic
- EJB Control — to control EJBs and JavaBeans
- Web Control/Model — Web-tier control tags and JavaBeans
- View — JSP, servlets, JavaBeans, or Java applet or application
These four layers can benefit your application in numerous ways. For example, because of the architecture’s simplicity, it is easy to explain and demonstrate where each object’s role fits into the big picture. Moreover, if the E++ language is carefully followed, the potential for reuse in different projects is guaranteed.
Pattern name: REAI architecture
Context
The company in question, TSP, needs to integrate with remote services including multiple, independent backend services that may use incompatible technologies. The architecture must determine what method invocations and messages go to what destinations, under what conditions, and what recipients do when receiving them.
The problem
How do you architect the application to integrate and automate the processes without depending on the backend services details? At the same time, can the rules of process flows be introduced and modified quickly by nonprogrammers in a cost-effective, manageable, and changeable fashion?
Force
For the processor, EAI (Enterprise Application Integration) presents challenging tasks. First, in an EAI environment, the processor must accommodate heterogeneous systems and applications. Second, it must launch each application required in the process flow. Finally, it must deliver and receive data in whatever forms the applications can handle. Considering these challenges, the processor will need message broker capabilities, such as the ability to transform and move data.
The solution
The REAI architectural pattern, as shown in Figure 5, can solve our problem by using a set of decoupled components, resulting in greater flexibility, maintainability, and changeability. The REAI architectural pattern consists of five modules:
- Task Scheduler
- Biz Rules
- Rule Engine
- Data Handler
- Dispatcher
To reach our solution, tear integration business-process logic out of application objects and encapsulate complex processes in rule scripts. This way error rates fall, and manageability, changeability, and lower developer intervention will be achieved.
Scheduler schedules B2B tasks, and the Rule Engine is loaded dynamically so that the application exists independently of any specific engine implementation. The engine executes rules and asserts business actions. The Data Handle layer ensures that when data reaches its destination, the format of the data is what’s expected. The Data Handle also secures the XML file if such security measures are required.
A B2B Dispatcher registers remote services and locates, adds, and removes exchange and remote services. It also serves as a gateway to available messaging services. The dispatcher employing these services should not depend on specific remote system details to guarantee portability and interoperability. If Sun’s Java Connector Architecture (JCA) is adopted by major application server vendors and the adapters become commercially available, then E++ may replace the dispatcher with JCA in future releases. However, at present the dispatcher is still valuable in helping applications integrate vendor-specific backend systems synchronously or asynchronously.
The REAI architecture provides the following benefits:
- It works with nonstandard adapters or facades of remote services
- One can change services or add new ones without modifications to the processing components
- It uses EJBs to conduct actual business, thus leveraging the existing security and transaction capability of the EJB container
- When network or remote server failures occur, new servers can be activated at a different network node without any impact upon clients
According to experience, REAI should be designed such that B2B administrators can control it in a quasi-seamless fashion, even with automation in default settings.
Conclusion
The E++ pattern language is a framework and pattern language for the development of e-business systems on the J2EE platform. As we’ve seen, E++ possesses the following important advantages:
- E++ can be developed prior to the completion of business-requirements gathering because it represents a flexible framework with event-based control logic. One needs only to create related events, event handlers, their EJB Model, Web Model, and business rules. The application control logic remains the same over time. Hence, the amount of time lost on coding that is often experienced when using Java may be reduced.
- It is easy to integrate different applications within an E++ master application. The framework allows the realization of an open and scalable system. The J2EE standard component implementation makes the framework truly portable over different operating systems and different application servers.
- E++ promotes a MREPICS-compliant application framework
In Part 2, we will work through E++’s detailed design patterns, so stay tuned.