|
|
 |
December 2001
Most J2EE projects I run across today have little in the way of analysis and design deliverables to show how they got where
they are. The whole endeavor lacks the ability to be tracked; that is, it lacks traceability. In this article, I present
the Use Case pattern as a mechanism to improve a projects chances of hitting its delivery goal, but more importantly, as
a mechanism that establishes a sound architecture that is much more accommodating to future change. The Use Case pattern
provides J2EE applications with more insight into how new applications, and modifications to existing applications, will
affect such things as the selection of the type of EJB component and the ramifications to existing transaction boundaries.
When we hear the word pattern, it is usually in the context of design patterns. However, design patterns are typically
used in a tactical sense, attending to one vertical challenge of the application. The important question to ask is how can
patterns be applied in a strategic sense, taking into consideration all the aspects of a projects lifecycle? For instance,
little is provided in the way of patterns that focus on the testing aspects of the project. An even larger gap that is
created in the rush to the design pattern is the projects inability to absorb future change. For instance, if the
application needs to change, either during development or after the move to production, how does the team trace the
effects both forwards and backwards? Fine-grained design patterns just dont get their maximum benefit unless a super
pattern for the entire project is brought into focus at the same time.
The Use Case Pattern is a super pattern that encourages project teams to recognize the needs of all the players on the
project and more importantly, to instill traceability as a key goal of all deliverables. The Use Case Pattern relies on
three artifacts that the UML offers : the Use Case, Class, and Interaction Diagrams. Diagrams in and of themselves are
useless without some level of additional support material. This is especially true of the Use Case diagram, whose worth
would be suspect without the support of an accompanying template.
Use cases represent the uses of the application. Use cases are coarse-grained and if presented with one, the user will
tell you they represent major categories of functionality. As an example, Take Orders is a use case in an online shopping
cart application. However, Verify Customer Number is merely a step in the course of some pathway in that use case and is
not a use case in its own right. A use cases template then,describes several pathways through a use case. These pathways
can range anywhere from the happy path, or the most commonly occurring pathway, to alternate pathways, and of course
exception paths, or as one of my clients calls them crappy paths. Figure 1 provides a brief view of a use case diagram
and its happy path. We can also make the bold statement that every single pathway is testable. Quite early in the inception
phase of the project, the testing team can create test cases, or use case scenarios, to exercise every pathway in an
application.
Figure 1 Use Case and Happy Path
Most software engineers today know the purpose of the class diagram. Classes represent both the structure and behavior of
some collection of real-world entities in the system. The UML defines three types of classes: boundary, control, and
entity. Most classes in an application, particularly the entity classes, are found directly in the use cases. However,
as we shall see in a moment, the use case is also a key source of both the boundary and control classes as well.
The UML offers two forms of interaction diagrams: the sequence diagram and the collaboration diagram. It is important to
state early in the discussion of interaction diagrams that they are design models of the pathways through the use cases.
They represent objects bubbling with excitement, sending messages to one another to satisfy the ultimate goal of the user.
From the UML diagrams described so far, traceability is afforded both forward and backward. If requirements change, we start
with the use case and assess the impact on the remaining two diagrams.
So what does all this have to do with Java? This is where the architectural aspect of the use case pattern comes into play.
One might still get the diagrams right but quite often when I go into a client project, there is still no bridge between
what the diagrams describe and the code. At this point, the diagrams become dead, lifeless hulks of some previous view
of the application. What follows in the remainder of the article are the pieces that tie the applications deliverables
in the analysis and design portion of the application to what we deliver in the form of code.
First, every use case the application defines will have an associated use case control class created for it. Control
classes act as coordinators of activity. Others have also suggested this approach as a means to limit access to the internal
workings of the application as well as a way to reduce network chatter. Second, every happy and stand-alone alternate path
in that use case will have a corresponding operation defined in its related use case control class. The method implementing
the operation will directly manage the messaging defined in its corresponding interaction diagram (sequence/collaboration).
Exception paths are usually dealt with within the course of some other pathway. The same is true for variation paths, which
are alternate paths that dont stand on their own, but are merely left or right turns along the course of some other
pathway.
In the EJB world, these use case control classes are implemented as Session Beans. Depending on the nature of the use case,
the session bean may be either a stateless session bean (SLSB) or stateful session bean (SFSB). If you follow the suggestion
of Tyler Jewell in his excellent article Stateful Session EJBs: Beasts of Burden
http://www.onjava.com/pub/a/onjava/2001/10/02/ejb.html , one would hope they would all be SLSB. Each use case session
bean will have a corresponding operation as described above which implements the messaging defined in its corresponding
interaction diagram. Most of the messaging within the use case operations will be directed at entity beans. However, it
could be directed at other session beans as well, particularly if you have includes relationships between use cases.
In the non-EJB world, all the classes referred to are simply Java Beans. However, the architecture is identical.
Figure 2 provides an overview of the traceability afforded by the Use Case pattern.
Figure 2 Mapping of Components using the Use Case Pattern
As Figure 2 shows, there is an order to the progression of mapping to components: (1) From use-cases we find our entity
classes (2, 3). (4) From the use-cases we create interaction diagrams (e.g., sequence/collaboration) that model our classes
now acting as living objects sending messages to one another with the sole purpose of accomplishing the goal of the
use-case pathway. (5) For each use-case, a use-case controller will be implemented as either an SFSB or an SLSB. This
use-case controller bean will contain operations that implement the orchestration logic to carry out an individual
interaction diagram. Again, these map directly to the use-case pathways.
This pattern also quite successfully predicts how transaction boundaries are distinguished. Many times I see projects
struggle with where to place the logic that controls the boundaries for the pathways through the application. With the use
case pattern the guesswork is removed. All transaction demarcation occurs within the use case control classes, ALWAYS. In
the case of EJB applications, each method within each use case session bean is assessed as to its need for a transaction.
All update-oriented operations in the session beans will be marked RequiresNew. All other operations in the session beans
will be marked Supports. All entity beans can be marked at the bean level as Supports.
Right away, without going any further, we have some awesome traceability going for the project team at this point. New
requirement? Find which use case the requirement belongs to (perhaps it is a new pathway or a variation on an existing
pathway), find its owning use case control class and related operation which houses the messaging for the pathway and
assess the impact. This is where the leap over the wall usually happens in most architectures I run across. There may
be use cases defined for the project but the resulting code implementing the behavior has absolutely no traceability back
to the use case. In this approach, everything bridges back to the use case What a novel idea, actually tying code back to
the reason were building the code in the first place. This way, the test team knows the impact on their test plans and
even the users know the impact on any training documentation or procedure manuals they might be creating.
The good news isnt over yet. What about the externalization of what the use case pathways represent? If we have a pathway
through the Order Inquiry use case, where do we describe what the results look like? One requirement may demand the
result be delivered as an HTML page. Another requirement might also require it be rendered on a cell phone or PDA device
using Wireless Markup Language (WML). The inner workings of the use case control class method which implements the
interaction diagram for the order inquiry pathway should be void of any display logic. It should function the same
regardless of what its ultimate destiny may be. This is where the notion of the use case realizations comes into play.
A use case realization can be thought of as an instance of a use case pathway which considers its unique rendering
requirements. For both the HTML and WML implementations, there is an interaction diagram that deals with its unique user
interface requirements. However, both the HTML and WML requirements would utilize the services of the sequence diagram
implemented in the use case control class that just deals with returning a value object back to the order information.
How we choose to render the result is done in both a user interface boundary and a control class. In the Java world
(regardless of EJB/non-EJB status) this is accomplished using two architecture components: A Servlet that initially
intercepts the client request (control) and a Java Server Page (JSP) to render the output back to the client (boundary).
Using custom tag libraries, a JSP page would format WML back to the PDA device and yet a different JSP page would format
HTML to the browser. Figure 3 shows a UML component diagram outlining the different components working together.
Figure 3 UML Component diagram with the Use Case pattern
The use case pattern provides a framework that serves the needs of many project participants. It provides a basis for all
project communication regardless of the lifecycle phase of the project. Of premier importance is the traceability it
provides the project. Impact analysis due to change is built into the application by virtue of its architecture. When
to use session beans is now quite clear. The operations in the session beans are also direct decendents of the interaction
diagrams created during design. EJB transaction definition decisions become less of an issue because all work begins with
the session bean acting in the role of use case controller. The application also benefits from a more agile use of the UML,
focusing in on those key artifacts that provide the application the biggest bang for their buck. The use case pattern can
go a long way towards providing more predictability to not only the end result of a project deliverable, but also to the
ability of the application to discover, assess, and absorb future change.
This article is a synopsis of the topics covered in the book, "Developing Applications with Java and UML" published by Addison-Wesley (Nov 2001) by Paul R. Reed, Jr. Paul is president of Jackson-Reed, Inc. (www.jacksonreed.com), a training and consulting firm that focuses on the implementation of Object-Oriented and Distributed systems for clients in the United States, Europe, Asia, and the Middle East. Reach Paul at prreed@jacksonreed.com.
PRINTER FRIENDLY VERSION
|