| CONTENTS | PREV | NEXT | INDEX | J2EE BluePrints |
This section describes the architecture of the pet store application; exploring the partitioning of functionality into modules, the assignment of functionality to tiers, and object decomposition within the tiers.
This discussion reviews the shopping interaction scenario once again, this time identifying actions within the application as it runs on the server. This replay is used to explore ways to divide the application into modules based on similar or related functionality. Dividing the problem in this manner reduces the dependency between modules, allowing them to be developed somewhat independently. Identifying the interface between modules enables some of the modules to be provided by third-party component providers, or subcontracted to specialists in a particular area of functionality.
Here's the scenario once again, with the various behaviors organized by modules:
This time, the run-through of the scenario has identified the following modules and their responsibilities:
- User account module: The application tracks user account information. This includes a user identifier and password and various types (billing and email addresses, phone number, and so on) of contact information. The application saves user account information to a database so that it spans sessions.
- Product catalog module: The application allows the user to search for products or services and be able to display details of individual products. The product catalog includes descriptions of individual items.
- Order processing module: The application performs order processing. Order processing occurs when the user performs the check-out process and buys the items in the shopping cart.
- Messaging module: The application sends confirmation messages.
- Inventory module: The application maintains information on the number of each type of product in stock.
- Control module: The application allows users to browse the product catalog and add selected items to a shopping cart. At any time, the user can modify items in the shopping cart, add new items, or remove items already placed in the cart.
Figure 10.2 shows the interrelationship of the modules in the sample application.
This modular decomposition of the pet store application is reflected in the subpackages of the sample application's top-level package com.sun.estore:
Partitioning the application into logical modules is the first step in subdividing the overall problem. The next step is to begin the process of object-oriented design of the application, identifying units of business logic, data, and presentation logic and modeling each of them as a software object.
The process starts by identifying the options and approaches available at the highest level. Once these choices are clear and the decisions and design principles are established, the rest of the design will be simplified by leveraging these overall principles.
One of the first decisions to make concerns the tiers that the application uses. The J2EE platform is designed for multitier applications, and offers a lot of flexibility in choosing how to distribute application functionality across the tiers. In a Web-enabled application, such as the sample application, some tiers are always present: the client tier provided by the browser, the Web tier provided by the server and the enterprise information system or database tier which holds persistent application data. The first choice to make is whether the Web tier accesses the enterprise information system resources directly, or goes through an EJB tier. The decision depends on the functionality, complexity, and scalability requirements of the application. Since such requirements can change as the application evolves, one goal for the design is to make it amenable to migration to an EJB-centric approach.
After deciding what tiers constitute the application, the next decision is how to distribute application functionality across these tiers. This division is closely linked to how the application is divided into objects at the highest level and represents one of the most important decisions when designing enterprise applications. Some clear and simple guidelines to help with making this decision are addressed in the following discussions.
10.2.2.1 Application Tiers
In a Web-centric design, the Web tier communicates directly with the enterprise information system resources that hold application data. In this approach, the Web tier is responsible for almost all of the application functionality. It must take care of dynamic content generation and presentation and handling of user requests. It must implement core application functionality such as order processing and enforce business rules defined by the application. Finally, the components running in the Web tier must also manage transactions and connection pooling for data access. Because it must handle so many functions, Web-centric application software has a tendency to become monolithic. As a result, unless special efforts are taken, it does not scale well with increasing software complexity.
In an EJB-centric design, enterprise beans running on EJB servers encapsulate the enterprise information system resources and the core application logic. The Web tier communicates with the EJB tier instead of directly accessing the enterprise information system resources. This approach moves most of the core application functionality to the EJB tier, using the Web tier only as a front end for receiving client Web requests and for presenting HTML responses to the client.
The principal advantage of this approach is that enterprise beans have access to a broad set of enterprise-level services. Because of these services, managing transaction and security aspects of the application is easier. The EJB container provides a highly structured environment for the components that allows a developer to focus entirely on the application domain issues, while the EJB container takes care of system-level details. These standardized container-provided services also translate into better software reliability. The EJB architecture supports a programming discipline that promotes encapsulation and componentization, resulting in software that stays manageable as applications grow more complex.
The Web-centric approach is better for getting the application off to a quick start, while EJB-centric approach becomes more desirable when building a large scale application where code and performance scalability are prime factors. While the Web-centric approach may be more prevalent, with many applications implemented using it, it has limitations when building large scale, complex applications.
The ideal solution is an approach that benefits from the strengths of both approaches. The sample application demonstrates an approach that started out simple and small, but kept the option of growth open. Its extensible design started as Web-centric and migrated to an EJB-centric architecture. While most of its modules are implemented with an EJB-centric design, the catalog module uses the Web-centric model. Strategies for migrating components from Web-centric to EJB-centric designs are described in detail in Section 4.7.1.
Note that the discussion that follows describes a sample application design that evolves from Web-centric to EJB-centric. The actual code of the sample application reflects the final result of that migration. We have preserved the state of the catalog module before migration to provide an indication of how the migration was performed.
10.2.2.2 Application Objects
The next issue to address in developing the overall application architecture is how to subdivide the application into objects and how to the assign these objects to tiers. This process is referred to as object decomposition. While most of the objects are consigned to one tier or another, there are some that serve to connect the tiers and will need to span tiers, and their design needs to take this into account.
This discussion focuses primarily on large scale, complex applications. Smaller applications can probably get away with less rigorous treatment, but object design really becomes important as applications grow more complex. Large scale development of object-oriented software requires frameworks. It is important to have a framework, so that every time the design requires two objects to interact, a developer does not have to come up with a whole new notion of how the interaction works out.
This section looks at the issues to keep in mind when doing the object decomposition, and present techniques that we used in the sample application to determine an effective decomposition.
Consider the kind of goals that need to be addressed in object decomposition. Each of these considerations identifies criteria to use to divide the application. The framework must enable:
While these requirements apply to object-oriented design in general, they become even more important for multitier enterprise applications. Our additional objectives were:
- Separate stable code from more volatile code. All parts of an enterprise application are not equally stable. The parts that deal with presentation and user interface change more often. The business rules and database schemas employed in the application have a much lower propensity to change. The overall architecture should separate stable portions of the application from parts that are more volatile.
- Divide development effort along skill lines. The people that comprise an enterprise development team typically represent a very diverse set of skills. There are HTML layout and graphics designers, programmers, application domain experts, and enterprise information system resource access specialists, among others. The decomposition should result in a set of objects that can be assigned to various subteams based on their particular skills. This division of labor allows work on each object to proceed in parallel.
- Ease migration from Web-centric to EJB-centric design. As mentioned earlier, the sample application starts out as a Web-centric application and migrates to being EJB-centric.
We have described these considerations from the point of view of a high-level division. However they are equally applicable even when we are working on identifying objects at a finer level. We will keep coming back to these considerations as we need to make choices about object decomposition.
When applying the considerations discussed above to the sample application, the first lines of division start becoming clear. At the highest level, the application divides into three logical categories of objects. These are objects that deal with presentation aspects of the application, objects that deal with the business rules and data, and objects that accept and interpret user requests and control the business objects to fulfill these request.
The look and feel of the application interface changes often, its behavior changes less frequently, and business data and rules are relatively stable. Thus objects responsible for control are often more stable than presentation objects while business rules and data are generally the most stable of all.
The implementation of presentation objects is typically handled by graphics designers, HTML and JSP technology experts, and application administrators after the application has been deployed. Control-related objects are implemented by application developers. Business rules and data objects are implemented by developers, domain experts, and database experts.
The presentation logic of a user interface can be handled by the Web tier or the client. In the Web tier, JSP pages are used to dynamically generate HTML for consumption by a browser. A stand-alone client, such as the one described in the administration scenario in Section 10.1.1.2, provides its own presentation. Control-related objects are present in each tier to enable coordination of actions across tiers. Objects that model business data and rules live in the EJB tier in an EJB-centric approach, and in the Web tier when using a Web-centric approach.
As discussed in several chapters in this book, the MVC architecture can be easily applied to enterprise applications. The presentation, business, and control categories map respectively, to the view, model, and controller concepts defined in the MVC architecture. The following sections take a detailed look at the design, implementation, and interactions of the sample application objects that constitute the view, model, and controller.