![]() |
|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
|
![]() |
![]() |
SummaryBy Jian Zhong
The Java 2 Enterprise Edition (J2EE) Platform is defined by four key pieces: the specification, the reference implementation, the compatibility test suite, and the BluePrints program. BluePrints describes the best practices and design guidelines for a distributed component architecture. This article introduces an eight-step J2EE development methodology based on the Rational Unified Process and the BluePrints sample application. By reading this article, you will better understand many important J2EE architecture topics, and be able to apply that knowledge to extend and modify this simple methodology to solve your special business problems. (3,600 words; September 28, 2001)
n the commercial world, we use Java 2 Enterprise Edition (J2EE) to
solve business problems, to develop commercial software, or to provide contract
services to other businesses' projects. If a company wants to build an
e-business Website using a multitiered architecture, it usually involves
managers, architects, designers, programmers, testers, and database experts
throughout the development lifecycle.
For different parties to work efficiently and effectively, they often need a software development process. Some classic development processes include the waterfall model, rapid application development (RAD), and extreme programming. In this article, we will focus on a popular software engineering process, the Rational Unified Process (RUP). RUP provides a disciplined approach to assigning tasks and responsibilities to different roles. Its goal ensures we produce high-quality software that meets user needs within a predictable schedule and budget.
I like to use RUP for J2EE development for three reasons. First, RUP is architecture-centric; it develops an executable architecture prototype before committing resources for full-scale development. Second, RUP is iterative and component-based. The architecture baseline often includes a framework or infrastructure to facilitate adding components through iterations to customize and extend a system's functionality without affecting the rest of the system. Third, RUP employs an industry-standard language, UML, to visually model a system's architecture and components. RUP has four different development phases: inception, elaboration, construction, and transition. This article, however, covers eight essential activities involved in J2EE development from a technical perspective in a manner that maintains the architectural focus.
I. Requirements analysis
The
requirements analysis describes what the system should or should not do so that
developers and customers can create an initial business contract. You can
document functional requirements in business concepts, domain glossaries, use
cases, and user interface (UI) mockups. Nonfunctional requirements, such as
performance and transactions, you specify in a supplementary requirements
document. You can create the high-level UI mockup on paper or in HTML, depending
on how deeply you are involved in the project.
Figure 1 shows two sample use cases of a typical e-business system. The
viewOrder
use case tells us that a user logs into a system through
a Web interface, sees an order list, and clicks a link to view order details of
a specific purchase order. The addLineItems
use case tells us that
the user browses a product catalog, selects interesting products, and adds them
to a purchase order.
Figure 1. Order use cases |
II. Object-oriented
analysis
Analysts generate problem domain models: classes,
objects, and interactions. Your analysis should be free from any technical or
implementation details and should contain an ideal model. Object analysis helps
you understand the problem and acquire knowledge about the problem domain. You
must maintain a pure domain model without technical details because a business
process changes much more slowly than information technologies.
These first two steps -- requirements analysis and object-oriented analysis -- are not J2EE-specific; they are quite generic for many object-oriented methodologies. Figure 2 shows a high-level object analysis model of a pet store sample application. It illustrates the major concepts we identified from requirements analysis use cases. We model these concepts into objects and identify their relationships.
Figure 2. Higher-level analysis model: The pet store
domain |
The result of requirements and object analyses is the entry point for J2EE architecture development. To develop an architecture, you select a vertical piece -- often a critical part, such as the order domain object model -- for object design, implementation, testing, and deployment. (A vertical piece, an RUP concept, is a small portion of a system. The starting point is a subset of use cases, as shown in Figure 1, and domain analysis models, as shown in Figure 3. The implementation of a vertical piece results in a fully functional mini-system including all the tiers, such as UI-tier JavaServer Pages (JSPs), middle-tier business objects such as Enterprise JavaBeans (EJBs), and often backend databases.) You can apply experience gained from the prototype to domain objects, and let that knowledge serve as a design guideline for the object design stage.
Figure 3. Detailed object analysis model: Order
|
III. Architecture
specification
After the first two steps, the business domain
problems and requirements should be clear. Now we'll focus the effort on the
technical strategies and architecture. An architecture is a blueprint of all the
parts that together define the system: the structure, interfaces, and
communication mechanisms. We can further divide an architecture into enterprise
and application architectures.
Enterprise system architecture
Enterprise-wide system
architecture covers hardware and software infrastructure, network topology,
development, testing, production environment, and so forth. These reflect an
enterprise's long-term investment. Before development, you want to evaluate your
existing software and hardware infrastructure and possibly add new components
and upgrade your existing system if it cannot fully support J2EE. You need to
thoroughly evaluate hardware, including computers, routers, network switches,
and network topology, as they all impact system performance and reliability.
Figure 4 shows a possible multitiered network topology.
Figure 4. Enterprise architecture: Network topology
|
A possible multitiered enterprise architecture shown in Figure 4 has the following major components:
The system architecture type you use depends on your requirements for security, performance, and reliability, as well as your organization's financial situation. At the least sophisticated end, you can reasonably run a simple second-hand computer in a garage with a phone line. There are many open source operating systems, Web servers, application servers, and database management systems available through the Internet. This system type's cost would be a few hundred dollars and a few sleepless nights.
High-end customers, such as many Wall Street financial institutions, might require a system that continually supports security, high throughput transactions, and unpredictable network traffic. In this situation, you commonly need an n-tier architecture with Web servers and application servers configured as clusters for fault tolerance.
You also need to evaluate the software infrastructure, including the Web server, security management software, application server, domain name management server, database management system, and third-party software components. If you have not purchased your application server yet, selecting a J2EE vendor is an important aspect of this evaluation process. I should note that different vendors implement J2EE quite differently, and some vendors only support old J2EE versions. Additionally, some Web containers or application containers might be faster than others. Other than implementing the J2EE specification, many vendors might also sell J2EE infrastructure components or frameworks. Selecting a stable J2EE vendor who provides support is also critical. Common functionalities that you can purchase or develop at the system infrastructure level include:
Application architecture
Application architecture, built
on top of an enterprise-wide system architecture, refers to a specific project
or application. After the infrastructure is complete, the architect studies how
to build a specific application. If your enterprise architecture only partially
supports an old J2EE version, you might first upgrade your system. If you cannot
upgrade due to budget or timing concerns, then you may have to work within the
technical constraints associated with older versions. While it's important to
build enterprise-wide reusable components, you first must be able to
use in order to reuse. The ultimate goal here is to satisfy
customer requirements -- one project at a time.
An architect is not a designer; architecture and design are two different things. An application architecture's scope is the system's major structure, its architectural design patterns, and the frameworks upon which you can add components. The architecture's major concern realizes nonfunctionality, whereas design is concerned with the business use cases you apply to convert the domain object model into a technical object model. Application architecture is the project's structure, a particular application. Common application architecture decisions you must make through application architecture development include:
The order domain objects in Figure 3 demonstrate how you can model domain objects. With current Java technology, you could distribute domain objects among Web containers as developer-managed persistent objects, EJBs in the application server, or as RDBMS-hosted Java stored procedures.
In the BluePrint pet store, we design the order object as an entity bean, a detail object, and a data access object as shown in Figure 5 and later in Figure 6. When you see this, you should realize its architectural significance. Ask why a domain object in an analysis model maps into so many objects. Ask what would happen if you change the design. You might have heard good things about EJBs, but be aware that the performance of different vendor implementations varies. When a new technology comes along, you need to research and perform hands-on work before plunging into a full-scale design effort. You can often apply the lessons learned about designing and implementing the domain object model's vertical pieces to the design of many other domain objects. This is what architecture development is about.
Figure 5. Order object design model |
In the early J2EE days, some object-oriented designers tried to map domain objects into entity beans and pass them across tiers. They obtained nice UML diagrams, but the result was a slow system due to unnecessary network traffic. To go from object analysis directly to object design without architecture development, without clearly understanding a new technology, almost always leads to project failure.
Architectural deliverables
As J2EE architecture is a
relatively new topic, the deliverables for a J2EE architect are not well
defined. From the pet store sample application, it is difficult to see where
architecture stops and design begins. The document begins with a high-level
examination of the application architecture, a discussion of the
Model-View-Controller design pattern, and an architecture overview. The
low-level documentation is available in the source code. There are no UML
diagrams. The assignment part of Sun's J2EE Enterprise Architect certification
requires all deliverables to be in UML. However, the marks only distribute into
one class diagram, one component diagram, and a few object interaction diagrams.
These are far from sufficient for real-world J2EE applications. To get started,
the architecture specification and process requires at least the following:
After you develop several J2EE solutions and gain more experience, the prototype becomes less important and a few UML diagrams and some design guidelines may be sufficient.
IV. Object design
Guided by
architectural specifications, the design technically expands and adapts the
analysis result. While domain object modeling at the analysis phase should be
free from technical details, the object design fully accounts for technical
factors, including what kind of platform, language, and vendors are selected in
the architecture development stage. In analysis, you keep your eyes on the
stars, but at the design phase you put our feet on the ground. Theoretically,
you shouldn't tamper with business objects unless absolutely necessary in order
to maintain their basic properties and behavior.
Guided by architectural decisions, a detailed design effort should address specification of all classes, including the necessary implementation attributes, their detailed interfaces, and pseudo-code or plain text descriptions of the operation. The specification should be detailed enough so that, together with model diagrams, it provides all the necessary coding information. In many automated software production processes, you can generate code skeletons from object-oriented diagrams. Figures 5 and 6 illustrate a high-level and detailed object design for a few domain objects. Note that the stubs and skeletons are not usually shown in diagrams as they are transparent to the designers and programmers. I've included them in Figure 6 to illustrate EJB basics.
Figure 6. Object design model: Order EJB detailed
design |
After you finish the detailed object design, you complete the object-relational mapping of domain objects. The reason for this is that although object-oriented methodologies are pretty advanced now, the most popular and mature persistence stores are relational. Additionally, a customer's IT infrastructure in many cases already reflects existing investments and preferences for commercial RDBMS vendors. So converting domain object models into relational models, or database tables, is very important. There are many container-managed persistence tools, but they cannot replace a good relational database design.
V. Implementation
With a good
architecture and detailed design, implementation should be a clear task.
Additionally, because we designed and implemented a vertical piece of the system
in the architecture prototype stage, fewer surprises should exist in the
implementation stage. In many organizations, developers often arrive at the
implementation stage too early. This problem is exacerbated when managers peer
over developer shoulders to ensure they're writing code since, to them, anything
else wastes company time.
As a result, instead of drawing UML sketches in hours or days, ideas are often tested concurrently with code development, which may take weeks or months. Since, in such circumstances, all the architectural decisions and design are made during coding time, discovering that development has moved in the wrong direction often takes several months.
VI. Validation
Validation consists
of testing to verify that the system works as designed and meets its
requirements. The validation process occurs both in the development and
production environments throughout the development lifecycle. Unit testing,
integration testing, and user acceptance testing are important subjects unto
themselves.
VII. Assembly and
deployment
Component assembly and solution deployment is
especially important in J2EE development. The development and production
environment could be quite different. If EJBs are in the system, you need to
produce container-generated classes using vendor-specific tools since, as I
pointed out previously, Web or application component configuration could vary
with different vendors. You must also consider whether the system to be deployed
has any vendor-specific code implementation. In an extensible architecture, the
system structure should be stable but should also support incremental deployment
of new or old components without affecting the whole system.
VIII. Operation and
maintenance
During the final stage, the application is in the
hands of its users, for whom you must provide training, documentation, and
education. Users will find bugs and might request new feature improvements. You
must handle these through proper change management procedures. You don't need to
shut down a working system in order to deploy a new component or replace an old
component.
Architecture development process
Knowing we must make
many architectural decisions, we must now figure out a process for architecture
development. For an enterprise, there are usually many application projects,
some of which could span several years, resulting in system evolution
encompassing many cycles. Many common requirements exist across many projects in
your domain. You should easily reuse an extensible and reusable architecture in
a previous project cycle later in its lifecycle or in other projects. There is a
need for common frameworks, reusable software architectures that provide the
generic structure and behavior for a family of software applications.
If this is your first J2EE project, your architecture must be prototyped, tested, measured, analyzed, and then refined in iterations. BluePrints provides many good design guidelines and best practices, and the pet store sample application serves as a nice reference architecture. The most efficient way to deliver good solutions quickly but with high quality is to embrace and extend the BluePrints reference architecture and then plug in your own business components. The last thing you want to do is reinvent the wheel.
Embrace a reference architecture
To my understanding, the
essence of the pet store architecture is the Model-View-Controller and the
Command patterns. You can apply these patterns to both Web-centric and
EJB-centric systems. For each domain object, a view is represented as nested
JSPs. A controller handles related business events, and domain objects
encapsulate business logic, transactions, and security. We use the front door
servlet as the central controller to receive and intercept all user gestures. It
dispatches business events to specific domain object controllers, which call
domain objects to change persistence states. Depending on this event handling's
result, a controller selects the next view to display. The following are
architecturally significant components that we can modify and use for most J2EE
applications:
MainServlet
: Front door component, interface between the Web
container and this framework
ModelUpdateListener
: Interface for objects interested in
getting the model update events
ModelUpdateNotifier
: Notify listeners when the update model
event occurs
RequestProcessor
: Processes all requests received from the
MainServlet
RequestHandler
: Interface for plug-n-play request handler
components
RequestHandlerMapping
: Contains request handler mapping rules
RequestToEventTranslator
: Central request handler delegates
request handling to plug-n-play request handling components according to
request handler mapping rules. Translates http requests to business events
EStoreEvent
: Business event
ShoppingClientControllerWebImpl
: Proxy-to-EJB tier front door
controller
ScreenflowManager
: Controls screen flow, selects views
ModelUpdateManager
: EJB tier model update manager, notifies
what models are changed due to an event
ShoppingClientControllerEJB
: EJB tier front door, provides
remote service to EJB clients
StateMachine
: Central event handler, delegates event handling
to plug-n-play handler components according state handler mapping rules
StateHandler
: EJB tier state handler interface
StateHandlerMapping
: Contains state handler mapping rules
Extend the reference architecture
While the BluePrints
sample application is a good starting point, you should modify it for each
project or domain. Design patterns are reusable microarchitectures that you can
use to extend the reference architecture. BluePrints, which provides a useful
J2EE patterns catalog, and the 23 "Gang
of Four" patterns are both excellent resources. For example, if you want to
extend the reference architecture to support workflow management, you could
dynamically register event handlers with the central controller at deployment
time or runtime. The central controller asks each event handler registered to
handle an event until a handler returns a message to indicate the end of the
command chain.
Plug in your business components
The J2EE technology is
the same for everybody, but the problems we try to solve could be quite
different for diverse domains. Once you establish a basic J2EE framework, you
must then realize a few use cases to show that the architecture actually works
for your domain. You do this by selecting the scenarios, which capture the
system's critical functionality, that are used most frequently and present
significant technical risk. Starting from the domain analysis model, you then
try to map your domain objects into high- and low-level design models just like
we did in Figures 5 and 6. Implement the low-level design models and test it to
see if they actually work. If everything works as intended, begin the next
iteration by reassessing the risks, extending the scenarios to consider, and
selecting a few more scenarios to extend architecture coverage. After a few
iterations, the initial architecture prototype should become stable. Identify
what components you can purchase, what legacy systems you should preserve, and
how you can interface them. The next step is software design, where you can
continue development using similar methods and processes as specified in the
design guidelines.
Step by step
We use a process to
divide a complex problem into smaller ones so we can more easily understand and
solve them. In this article, we divided J2EE development into eight steps,
focusing tightly on architecture and design. I've addressed important
architecture topics and presented a process for making architectural decisions.
I also discussed the roles and deliverables of a J2EE architect.
Learning to develop J2EE solutions using these steps is much like learning
the steps to a dance. You first need to practice the basic movements consciously
and diligently. But once you are more familiar with them, you want to put them
all together and focus more on the size, speed, flow, and rhythm of each step in
a specific context. But you should never let a process limit creativity.
Instead, embrace and extend the process to fit your particular needs. Remember,
your ultimate goal is to deliver a complete J2EE solution that satisfies your
customer's requirements.
About the author
Jian
Zhong, a senior software architect with ActioNet Inc., has been actively
involved in J2EE architecture development for the last two years. He started
Java programming in early 1996 and has been a Sun Certified Architect for the
Java 2 Platform since October 1999 and a Sun Certified Enterprise Architect for
the J2EE Platform since November 2000. Jian would like to thank Lindsay D.
Ridgeway for in-depth discussions on many architecture topics while working in
the CTO Group at SpaceWorks Inc. He would also like to thank Jeffrey D. Abish
and Elisabeth A. Kinner for help in reviewing this article.
![]() |
![]() |
|
![]() |
Copyright © 2001 JavaWorld.com, an IDG Communications company |
![]() |
![]() |
![]() |