 | Level: Introductory Gary Evans, Independent Object Technology Evangelist, Evanetics
13 Aug 2004 from The Rational Edge: The second of a two-part series on transforming the requirements captured in use cases into implementable representations and code, this article presents the steps involved in Use Case Design activity within the Rational Unified Process, or RUP, where technology-dependent decisions are made.
This is the second part of a two-part series on transforming the requirements
captured in use cases into implementable representations and code. In "Part 1, Use case analysis," I traced the major steps in the Use Case Analysis activity
of the Rational Unified Process®, or RUP®1.
I introduced a simple case study for a vehicle rental system (let's now call
it Deals on Wheels) to be developed to offer browser-access to customers
wishing to reserve a vehicle, cancel a reservation, view a rental history, etc.
I presented a single use case, Reserve a Vehicle, first in a very generic
version, then in a supplemented version, introducing more of the external
interactions that have to take place in this use case.
Then I used the simple technique of grammatical dissection to identify candidate
entities in the use case, and introduced four questions to challenge these candidates.
These questions distilled our forty-one candidates down to eight entities that
passed the test of being analysis classes. Then I identified the responsibilities
of each analysis class, so we could have what James Rumbaugh et. al. call a
"crisp boundary" in our definition of each class.
With the eight analysis classes identified, I then introduced four steps
that I used to construct an initial analysis class diagram to capture the relationships
and multiplicities among these classes. Next, I constructed an analysis-level
sequence diagram of the main scenario of the Reserve a Vehicle use case.
This was strictly constrained to be an analysis-level diagram containing only
analysis classes, and no design or implementation classes. To improve understandability
of the sequence diagram, I introduced a generic use case controller object
to mediate the messages received by the human customer actor. With the
analysis classes and their relationships identified, I then populated each analysis
class with attributes (data members) that were in accord with the responsibilities
of each class. Lastly, I identified the analysis mechanisms for this
little case study.
In Part II of this series, we will perform the steps of RUP's Use
Case Design activity.
The elements of
Use Case Design in RUP
Figure 1 is taken from RUP's Analysis and Design Activity Overview.
It illustrates where the Use Case Design activity occurs within the context
of the other Analysis and Design activities.

Figure 1: Use Case Design activity in RUP
In RUP the stated purpose of Use Case Design is:
- To refine use case realizations in terms of interactions
- To refine requirements on the operations of design classes
- To refine requirements on the operations of subsystems and/or their interfaces.
We can alternately express that the goal of Use Case Design is to transform
each business abstraction in our system (i.e., the analysis classes) into one
or more design classes that are implementable representations, taking
into account the properties of the target execution environment. Note that the
design classes are implementable representations. The implementation
(i.e., coding) of the design classes occurs after design is stable (although
we sometimes write code to explore design options). In design, we want to express,
in appropriate detail, how we will approach the implementation so that the actual
programming is a matter only of language and platform issues. Figure 2 illustrates
the steps that constitute Use Case Design.

Figure 2: The steps of Use Case Design
The activity of design involves maintaining multiple perspectives simultaneously
on the software system you are building. Good designers successfully juggle
separate, and often competing, views of their target system. Just as a cube
has six faces which are independent yet part of the same whole, a software system's
design is multi-faceted, including: logical, process, implementation, deployment,
and operational views; system and software architecture; components and classes;
patterns and interfaces; static structure and interactions, and more. I am not
going to cover all of the practices of software design in this article. But
I will provide some concrete examples of what we might actually do inside the
major Use Case Design steps, as shown in Figure 2.
Classes
Object-oriented and component-based design strategies focus on classes -- which
are named units of data and bound functions that operate on that data. In the
design discipline, we describe our classes, and their relationships to other
classes or subsystems, in a manner that now takes all technology concerns into
account.
Some of these concerns are:
- How do I represent a one-to-many, or many-to-many, relationship between
two classes?
- How do I represent access to and from a data store?
- What aspects of my class should be visible to objects of other classes?
- Which aspects should be invisible to other classes?
- How do I provide a simplified interface to multiple objects?
- How do I appropriately separate the business behavior in my business classes
from the technology behavior that my executable system requires?
The Design Model
The result of our activities in Use Case Design will produce the contents
of the RUP Design Model, including (but certainly not limited to):
- The design classes (i.e., analysis classes plus technology classes) needed
in our system.
- Realization of the Software Architecture Document (SAD) content through
the design classes.
- The operations and attributes that each design class will own.
- Specification of actual data types, initial values, or interfaces for specific
subsystems or vendor-provided software.
- Partitioning of our system functionality by subsystem or architectural category.
- Interaction (i.e., collaboration and sequence) diagrams showing how our
design classes will collaborate to carry out the business process captured
in our use cases.
The Design Model will become the raw material that our implementation
discipline will transform into executable code. I reiterate that this discussion
will focus on a pure object-oriented approach for new system development (often
called "green-field" development) in C#, Java, or C++.
The steps we will discuss
When I do Use Case Design activity, I follow the steps depicted in Figure
2, with the exception that I add a step, as you can see in the following revised
list:
- Create use case realizations
- Describe interactions between design objects
- Simplify sequence diagrams using subsystems (optional)
- Describe persistence-related behavior
- Define design mechanisms (normally a Software Architect activity in RUP)
- Refine the flow of events description
- Unify classes and subsystems
- Evaluate your results
It is important to recognize that the order of these steps is not fixed. The
sequence you follow may differ based on your understanding of the domain you
are designing, your experience with RUP, your personal preferences for the models
you use, or the metaphor you follow for characterizing the properties of your
design classes (e.g., applying design patterns, or following principles such
as Separation of Concerns or the Interface Segregation Principle). What is important
is that you achieve a comprehensive expression of the solution approach you
will eventually implement.
Of the steps listed above, we will look closely at the subtleties of only the
five following steps:
- Create use case realizations
- Describe interactions between design objects
- Simplify sequence diagrams using subsystems (optional)
- Describe persistence-related behavior
- Define design mechanisms
Architectural criteria
To get started, since design is intimately constrained by and related to architecture,
let's consult our Software Architect (SA) and get an idea of the overall
architecture envisioned for our reservation system. For this discussion, let's
stipulate that the SA has produced a Software Architecture Document (SAD) that
indicates our architecture must support the following technical criteria:
- Scalability. Multiple, simultaneous customer sessions must be supported
in the Deals on Wheels reservation system and RDBMS. Each session must
be independent of all others, and the system must scale transparently to thousandss
of simultaneous customers.
- Maintainability. Updates to software components must be made easily
and centrally, with no distribution of business logic to browser platforms.
- Technical simplicity. Our rental company does not want to incur the
expense of training or hiring staff competent in full-fledged component environments
such as J2EE or .NET. These are overkill for our limited needs. The existing
staff are knowledgeable in Java, Java ServerPages, servlets, and JavaScript.
- Leverage technology. The Internet must be the communications medium
between browser and servers and the system must use existing programmatic
interfaces to legacy platforms.
With these criteria as givens, and knowing that the Deals on Wheels
project has Java and servlet developers on staff, the SA adds to the SAD the
simple UML architectural models shown in Figure 3.

Figure 3: Initial deployment diagram for kiosk system
Figure 3 illustrates the simplest view of the layout between an individual
client browser and the legacy Reservation DBMS, which contains reservation,
customer, and vehicle information. Figure 4 shows more internal detail as well
as some inter-process communication.

Figure 4: High-level physical architecture diagram
The diagram in Figure 4 reflects the high-level structure of our application
based on the JavaServerPage (JSP) Model 2 architecture. The customer interacts
with a browser on a client computer. The browser communicates via HTTP (Hypertext
Transmission Protocol) to the Web server, invoking servlets on the Web server.
I have shown only the Reserve a Vehicle servlet specifically. The servlet
acts in the role of a controller, coordinating the steps needed to carry out
the work of the Reserve a Vehicle use case. The servlet creates and interacts
with the business objects, such as Reservation, Customer, Protection Product,
etc., that the JSPs will need. The business objects (to be implemented as JavaBeans)
obtain their content from the legacy relational database management system (DBMS)
via a Java Database Connectivity (JDBC) protocol and interface. The servlet
forwards the service request to the appropriate JSP.
Use Case Design
step 1: Create use case realization for each use case
In Part 1 of this series, I indicated that a use case realization is really
a collection of several UML diagrams and other textual artifacts, such as RUP's
Use Case Realization Specification document, which together validate
that we have the classes, responsibilities, and object interactions necessary
to provide the behavior in our use case process.
In analysis, our use case realization contains only analysis classes and objects,
which may populate various UML diagrams such as class diagrams and interaction
diagrams. In design, our realization will contain design-level information explaining
how the steps of a use case will be carried out by collaborating design objects.
Class diagrams, interaction diagrams, and description, of derived requirements
will populate our design-level realizations. If you are using a modeling tool
such as Rational®Rose or Rational's XDE product, creating a use case realization
may simply involve creating a use case model element in the tool, and then creating
UML collaborations and interaction diagrams under that. If you are not using
a modeling tool, your realization may be a desk drawer containing hand-drawn
models or photographs of whiteboard models. Identifying and naming a use case
realization provides traceability from the interactions diagrams and textual
commentary back to the use case. The remainder of this article is basically
a discussion of the contents of the design-level use case realizations.
 |
Use Case Design
step 2: Describe interactions between design objects
This is a complex step, so be prepared to refer to several different figures
throughout this article, and to observe the iterative process at work. First,
note that as part of our Use Case Analysis activity in Part 1 of this series,
we produced the analysis class diagram shown in Figure 5 with attributes for
our vehicle rental system:

Figure 5: Analysis-level class diagram
This is an adequate, initial description of our analysis classes, and the relationships
between various classes, but it is not yet in an implementable form. For example,
how do we express in design that a given Reservation must have access to zero
or more ProtectionProduct objects? What does it mean that the relationship between
VehicleInventory and Vehicle is aggregation, but the relationship between
RentalLocation and VehicleInventory is composition? What data types do
we specify for Vehicle's status and specialEquipment attributes,
or Reservation's dates, times, or estimatedCost attributes?
Where do we discover operations to put into our classes? And, how do we represent
an interface to the Reservation RDBMS that lets us request, or store changes
to, a Reservation or Vehicle status?
Before addressing those questions, note that we can also review the analysis-level
Sequence Diagram (SQD) we described in Part 1 for the Check in a Passenger
use case, as shown in Figure 6.

Figure 6: Analysis-level sequence diagram (SQD)
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
In Use Case Analysis, our goal was to prove feasibility -- that our business
objects had the right responsibilities to carry out the steps of the Reserve
a Vehicle use case. We simplified our task by assuming all objects are eternal,
and we ignored creation and destruction of objects. But now, in design, we have
to explicitly demonstrate creation (and destruction, depending on the programming
language used) of our objects. We must also ask "who is in charge"
of accessing and "hooking up" the objects needed to service a customer
request.
Let's move into how we transform this sequence diagram into a design
perspective on the interactions among our objects. We start again with the Reserve
a Vehicle use case, specifically the "happy path" scenario where
nothing goes wrong.
How will this Reserve a Vehicle use case really start? The sequence
diagram snippet in Figure 7 captures a plausible interaction among objects.
(For simplicity, I am omitting in this sequence diagram the handling of the
customer profile that is in the analysis SQD.)

Figure 7: Design SQD of Reserve a Vehicle
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
When the customer visits the Deals on Wheels Website in Step 1, the
home page is visible on the customer's browser, presenting input fields that
the customer can fill-in to designate the location, dates, and category of the
vehicle she wishes to reserve. When the customer indicates in Step 2 she wants
the system to search for vehicles matching these critieria, the JSP posts the
form data to the Reservation servlet (RsvnServlet) in Step 3. The reservation
servlet has to verify that the selected rental location is actually open on
the dates and times selected by the customer, so in Step 4 the servlet creates
an empty RentalLocation object, and in Step 5 directs this object to populate
itself with the data for the location designated by the selected location identifier.
The RentalLocation has to obtain this existing information from our on-line
Reservation RDBMS, and in Step 6 I have added a new design class, DataAccess,
that implements the Façade pattern. This pattern lets us hide a complicated
interface by substituting a class or component with a simplified interface.
The RentalLocation object invokes a retrieveLocation(locationID) operation
on the DataAccess object, which returns a structured data row. In Step 7 the
RentalLocation calls a private operation on itself, fill(dbRecord), which
parses the data row and assigns the fields to its appropriate instance variables.
At the conclusion of Step 7, this instance of RentalLocation is fully populated
for a specific rental location. In Step 8 the servlet asks this specific rental
location, "Are you open at these dates and times?" through a validate(dates)
operation. In the "happy path" scenario we are discussing, the RentalLocation
replies "yes" (OK).
Since the location is open at the selected dates and times, the servlet will
obtain the list of vehicles matching the customer's request and have them displayed
to the customer. In Step 9 the RsvnServlet creates an empty instance of VehicleInventory
to hold the available vehicles matching the customer's criteria. In Step 10,
the servlet invokes a populate( ) operation on the VehicleInventory,
passing the selection critieria. Since the location inventory and knowledge
of vehicle availability is in an on-line data store, in Step 11 the VehicleInventory
invokes a method, retrieveVehicles(collection), on the DataAccess object.
The intelligence in this method knows to create an empty Vehicle object (Step
12), obtain the vehicle information from the corporate RDBMS (not shown), and
then in Step 13 invoke an operation, fill(dbRecord), on the just-created
Vehicle object. In fill(dbRecord) the Vehicle object parses the data
from the dbRecord (a data row), and fills in its own instance variables. In
Step 14 the DataAccess object adds the now-filled in Vehicle object to the VehicleInventory.
Steps 12-14 are repeated until all matching vehicles in the result set have
been deserialized into objects. Following Step 14, the VehicleInventory and
the servlet are notified that their requests have been completed.
The system now has to display the available matching vehicles to the customer.
In Steps 15 and 16, the reservation servlet stores the VehicleInventory object
in the Session object to be retrieved by the next JSP, and invokes the RequestDispatcher.forward(
) operation to display the ShowInventory JSP in Step 17.
In just this small snippet of our design SQD, we have almost as many messages
as the entire analysis sequence diagram. But in our evolution of the design
SQD, we have strictly demonstrated how our analysis and technical objects will
interact with each other to carry out the work of our Reserve a Vehicle
use case. We have determined that VehicleInventory really is just a collection
class to hold multiple Vehicle objects, and if we continued the SQD, we would
add another collection class to hold all the ProtectionProduct objects that
could be assigned to a Reservation.
At this point, we can reconstruct our class diagram (recall Figure 5) based
on the new technology classes and new operations discovered while developing
this part of the Reserve a Vehicle SQD, as shown in Figure 8.

Figure 8: First class diagram updated with operations
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
Let's step back and look at the larger picture that is developing. As
depicted in Figure 7, we adopted an approach that is known as the Java Server
Page Model 2 Architecture. This approach is a variation of the separation of
concerns principle embodied in the Model-View-Controller architecture. On the
left side of Figure 7, there are two JSPs. These are the presentation pages,
or views, that are displayed in a browser. In the middle of the SQD is the reservation
servlet, which is a controller that knows the steps that have to be carried
out to allow a customer to reserve a vehicle. On the right are the entity objects,
known as model objects, that have the business knowledge and business
relationships we need.
In our development of the SQD snippet shown in Figure 7, we discovered new
operations on three of our model classes: Vehicle, VehicleInventory, and RentalLocation.
So far, these are operations only to obtain data from on-line storage. As we
develop later parts of this SQD, or SQDs for other use cases, we would discover
more operations in all of our classes: operations for retrieval, storage, computation,
etc.
So let's not stop here. We've only looked at the behavior of getting
existing data from online storage into our objects. The next part of the rental
process starts when the customer selects a specific vehicle to reserve. In Figure
9, I show the SQD for this part of the process.

Figure 9: Design SQD for second part of Reserve a Vehicle
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
In Step 1 the human customer indicates that she wishes to reserve a specific
vehicle. This request is posted to the servlet, which asks the VehicleInventory
to mark the vehicle, denoted by a vehicleID, as unavailable temporarily. This
marking will prevent other rental customers from trying to reserve the same
vehicle. The VehicleInventory forwards this request to the Vehicle object for
the vehicle selected by the customer. The VehicleInventory does this with the
mark(expiry) operation, in which the expiry parameter is a timeout
period in case the customer leaves the page without completing the reservation.
Note that I have included a UML Note ("Update DB status as well?") here. As
a practitioner of agile development, I highly recommend that you use a modeling
tool only for models that have long-term value. But if you have a long-term
model with questions still awaiting resolution, feel free to include the questions
right into the model. You may not do this often, but the important point is
to get the issue into the open for all to see, and not lose it.
After marking the vehicle, the servlet needs to prepare for displaying the
Renter Information page, in which the customer verifies our information on her,
and the contents of her Customer Profile. Recall that I omitted the SQD section
in Figure 7 that described searching for the CustomerProfile, but now we need
the profile and the Customer object, too. In Step 5 the servlet obtains (presumably
from the HttpSession object, which is not shown) the customerID that would have
been entered on the Deals on Wheels home page. With this ID, the servlet
creates (in Step 6) a Customer object, directing it to populate( ) its
instance variables using the customer ID. In Steps 8 and 9 the Customer object
follows the now-familiar pattern of requesting its content as a dbRecord
from the DataAccess object. With the Customer object now instantiated and populated
for our specific human customer, in Step 10 the servlet notifies the Customer
object of its corresponding CustomerProfile. In Step 11 the Customer notifies
the profile that it is the profile's parent. Now we have a bi-directional assocation
between these two objects.
With this processing complete, the servlet is ready to display the RenterInformation
page, which it does with a RequestDispatcher.forward( ) operation. In Step 13,
the RenterInfo JSP page is active. In Steps 14-16, the JSP will obtain generic
information from the Customer and CustomerProfile objects and corresponding
data will display for confirmation. At Step 17 the RenterInfo page is displayed
to the customer's browser for confirmation and completion. In Step 18
the customer indicates she has affirmed, changed, or entered data onto the RenterInfo
page, and she is ready to continue the reservation. In Step 19, I again show
generically that the JSP will interact with the Customer and CustomerProfile
objects (remember, these are JavaBeans) to update them from the screen data.
In Step 20, the RenterInfo page posts to the servlet, indicating the renter
information is complete. After this we would model how the system presents the
summary information on the reservation, including offers to purchase protection
products, etc.
We have mapped out quite a bit of interaction in this SQD, and we have discovered
more operations on our classes. By promoting our SQD messages to operations
on the receiving classes, we have a new version of the class diagram, as shown
in Figure 10.

Figure 10: Second class diagram updated with operations
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
Now we see that we have added new operations to Vehicle, Customer, and CustomerProfile.
This is the iterative, use case driven approach at work. Starting with our use
case and list of classes, we choose objects from those classes to interact,
and we construct a SQD to show that interaction. The messages in analysis are
assigned to the classes based on the responsibilities we have given each class.
Then, the messages are promoted to operations on the class of the object receiving
the message. These operations are (in an ideal world) guaranteed to be needed
because they are generated to meet the goals of the use case that contains many
of the functional requirements of our system. Recall that this Use Case Design
step is named Describe Interactions Between Design Objects. In our SQDs,
we have certainly done that, and captured the static structure enabling that
interaction in our class diagrams.
Use Case Design
Step 3: Simplify sequence diagrams using subsystems (optional)
The next Use Case Design step is to simplify repeated behavior by replacing
common groupings of objects with a subsystem. In our example, we have already
identified a subsystem, the DataAccess object. This subsystem exposes
the retrieve ...( ) operations for obtaining object data from the datastore.
There is really a lot going on inside the DataAccess subsystem: generation of
SQL statements, error handling, result set management, etc. But the gory details
are hidden from the client objects requesting data retrieval (and later, data
storing).
Often we do not realize we need a subsystem (with simplified interface) until
we struggle with a complex set of classes and interfaces that we eventually
recognize have a natural affinity for each other (e.g., the classes in a Printing
Subsystem: Spooler, QueueManager, PrinterDrivers, etc.) A wonderful principle
for grouping classes into subsystems is Robert Martin's Common Closure
Principle:
The classes in a package [or subsystem] should be closed together against
the same kind of changes. A change that affects a closed package [or subsystem]
affects all the classes in that package and no other packages.
In other words, we need to group classes that have a common goal within a clear
boundary, so that changes within that package/subsystem are isolated to that
package/subsystem. And when we simplify our models by introducing subsystems,
we replace large sections of the sequence diagram with a single message to the
subsystem. This isolates the former complexity within the subsystem, and we
can develop separate models for the internal interactions of the subsystem,
which can now be a reusable component in our overall system.
Use Case Design Step
4: Describe persistence-related behavior
But, while we have correctly hidden some of the DBMS details behind the DataAccess
subsystem, we have actually made an egregious design mistake: Our analysis objects
(Vehicle, RentalLocation, ...) have knowledge of the DBMS. Analysis objects
should only know business-logic, not storage locations or storage methods, or
dbRecord structure layouts. Why is this bad? Consider the effect of a simple
change, which is the primary key for an object changes, and recall that our
current design has our analysis objects (e.g., RentalLocation) passing a specific
identifier (e.g., locationID) to the DataAccess object. If this identifier
is used as a primary key, and then changes, we will have to change the logic
in our RentalLocation object.
Is there a way to limit or eliminate this consequence on our analysis objects?
Yes. We can accomplish this logical isolation, in addition to the explicit
physical isolation described in our Software Architecture Document, by introducing
three new objects:
- A factory object, which creates our analysis objects for us, fully
populated from the DBMS
- A DB object, which is the DBMS-aware "twin" of an analysis
object
- A persistence interface, a subsystem that specializes in getting
information in and out of a datastore.
In the sequence diagram shown in Figure 11, we have introduced these three
objects and re-created the interactions where the servlet needs a Customer object
restored from on-line storage.

Figure 11: Design sequence diagram with persistence layer
Click to enlarge,
then find the four-headed arrow in the lower right of the screen to expand the
graphic to full size.
This is a much more encapsulated design, and allows for great reuse.
For each analysis object (e.g., Customer) that must be stored or retrieved from
the DBMS, we create a "DB-aware" ("database aware") object (e.g., DBCustomer)
that understands the data fields and format of its "normal" twin. These DB-aware
objects will reside on the Web server, and will be created and used by one of
the servlets. The DB-aware object knows how and where to connect, how to build
a SQL statement and get it executed, and how to take the result data and store
it into the analysis object. Now, changes to the DBMS format or result set data
structure are isolated behind the ObjectFactory layer, and the analysis objects
are not affected at all.
We must also evaluate our storage structure to make sure we can store, and
retrieve, the data required by our objects. Tables 1-7 indicate a sample logical
model of the Reservation DBMS layout. Notice that most of the fields in
these tables match the attributes in our classes. But some table fields (e.g.,
Table 3: Vehicle Date of Purchase) are not in our corresponding class
because fields like this are not relevant to the Reserve a Vehicle use
case.
Table 1: Rental location
LocationID <PK> | Street
Address | State | Sales
Region |
|
Table 2: Reservation
ReservationID <PK> | LocationID <FK> | VIN <FK> | CustomerID <FK> | StartDate &Time | ReturnDate &Time | Quoted
Cost | Payment
Method |
|
Table 3: Vehicle
VIN <PK> | Manufacturer | Make | Model | Assigned Location <PK> <FK> | Vehicle
Category | Date Of
Purchase | Current
Mileage | . . . |
|
Table 4: Protection product
ProductType <PK> | Eligibility
Codes | Lower
Limit | Upper
Limit | Benefit
Increment |
|
Table 5: Customer
CustomerID <PK> <FK> | Name | Street
Address | Email
Address | Business
Phone | Other
Phone | Drivers
License # | Issuing
State | License
Exp. Date | Date Of
Birth |
|
Table 6: Customer profile
CustomerID <PK> <FK> | Default
Vehicle
Category | Smoking
Preference | Default Damage
Waiver | Default Personal
Accident Insur. | Default Supplemental
Liability |
|
Table 7: Award program
AwardID/CustID <PK> <FK> | Current
Balance | YTD Redemptions |
|
Also, notice how the primary key (<PK>) and foreign key (<FK>)
properties represent the relationships on the Deals on Wheels class diagram.
The Reservation table knows about its corresponding Customer through the CustomerID
<FK> field. The RentalLocation table can obtain all of its assigned vehicles
through the Assigned Location primary key field in the Vehicle table. The SQL
statement created by the DB-aware objects will be generated based on the physical
data model for the database being accessed. The SQL statement "SELECT * FROM
VEHICLE WHERE ASSIGNEDLOCATION = 42355 ORDER BY VEHICLE.VEHICLECATEGORY" will
return a result set of all vehicles assigned to that rental location, ordered
by vehicle category (economy, compact, etc.).
Now we can appreciate this very important statement: the design classes
you discover and use will depend on the design approach you take. In our
first approach to addressing persistence, we put DBMS knowledge in the object
representing our business abstractions (i.e., analysis classes). But in our
second approach we created an additional layer of DB-aware objects that specialized
in getting data into and out of the DBMS.
Use Case Design
Step 5: Describe design mechanisms
In our analysis of our vehicle rental system, we identified a need for the
following analysis mechanisms:
Persistence. In a normal reservation session, or change reservation
session, the Reservation and Vehicle objects will undergo change of data and/or
state. So we need a persistence mechanism to store the new object data. In analysis
we need only to specify a meaningful name for the persistence store, but the
details of how we achieve this persistence will be addressed later in design.
Security. We do not want to show any reservation other than that of
the correct individual, so we specify a mechanism to assure authentication security.
Legacy interface. All vehicle information comes from the Corporate Vehicle
System that maintains centralized vehicle information for all rental locations.
How we talk with the Corporate Vehicle System depends on the design mechanism
choices we can use.
In design, we reevaluate and map these into design mechanisms that are
specific solutions to the analysis needs for persistence (Table 8), security
(Table 9), and legacy interface (Table 10). For each of these, I have additionally
shown the implementation mechanisms that will satisfy the design mechanisms,
as shown in Table 8.
Table 8:
| Mechanism | Persistence | | Design Mechanism | RDBMS -- Analysis identified the need to access and store object
information in a persistent fashion. Since our corporation has several
relational database management systems (RDMBSs), our design mechanism
will also specify RDBMS. We have staff who understand this
technology, and our existing data infrastructure includes tools (e.g.,
report generators) that require SQL as an interface. | | Implementation Mechanism | JDBC -- We have partially addressed this in the section above
that evolved the Factory class, DB-aware classes, and Persistence
Interface class. But exactly how will the Persistence Interface
access the target RDBMS? In our scenario, let us assume that the Reservation
RDBMS is an Oracle 9i system running on a Unix server, but may be
replaced by SQLServer running on Windows 2000. In this scenario, using
a JDBC interface to the RDBMS would give us the flexibility we need. |
|
| Mechanism | Security | | Design Mechanism | Authentication Security -- Analysis identified the need to
assure that a customer can see or change only his/her own reservations.
We will use the customer's Awards ID number, which is guaranteed
to be a unique identifier, as an index into the passenger data store. | | Implementation Mechanism | Unique Customer Number (Awards ID number) as unique identifier;
RDBMS index on Customer table. |
|
| Mechanism | Legacy Interface | | Design Mechanism | This mechanism is not necessary in our simple vehicle rental
system example. In our Use Case Analysis, we stipulated that our
vehicle information was maintained in the Corporate Vehicle System,
which was itself an RDBMS. Our persistence mechanism provides the
services we need to extract and insert information to our RDBMS.
If we had to communicate with a CICS application on an IBM MVS
mainframe, then we would need to specify the communications protocol
we would use (e.g., LU 6.2 APPC). | | Implementation Mechanism | None. |
|
Conclusion
In this two-part series of articles, I have provided numerous examples to illustrate
how to move from initial use cases containing many of our system requirements,
to analysis of our problem domain, to design of our solution domain in the context
of the specific technical dependencies of our production environment. There
are many more topics that have to be considered in system development, but I
believe these examples satisfy my limited goal of offering a practical tour
of the process. Given the level of detail in our design-level sequence diagrams
and class diagrams, the reader should be able to see that translating these
representations into Java class definitions or JSPs is a straightforward exercise.
With our design artifacts, we can move directly into coding a proof-of-concept,
or writing the production code for our system. Each use case will follow the
process in these articles until, when all use cases have completed this iterative
cycle, we will have most of our system coded, and we will have coded all of
the significant business functionality that was captured in our use cases.
 |
References
Rumbaugh et al., Object-Oriented Modeling and Design. Prentice-Hall,
1991.
Robert C. Martin, Agile Software Development: Principles, Patterns, and
Practices. Prentice-Hall, 2003. An award-winning book that covers a broad
menu of essential design practices.
Eric Gamma, et al., Design Patterns: Elements of Reusable Object-Oriented
Software. Addison-Wesley, 1995. Required reading for any developer doing
serious development today.
Further Reading
Scott Ambler, Agile Modeling. Wiley, 2002. How to do more with less
modeling and overhead.
Len Bass, et al., Software Architecture in Practice. Addison-Wesley,
1998. Excellent coverage of what software architecture really is.
Notes
1 All references in this series to RUP incorporate the content of RUP version 2003.06.00. All UML models in this series have been generated using IBM/Rational Extended Developer Environment (XDE) Developer Plus for Java version 2003.06.
About the author  | |  | Gary K. Evans is the founder of Evanetics, Inc. (www.evanetics.com), a consulting company dedicated to reducing risk on software projects through agile techniques and process. He is the author of over a dozen papers on object technology and tools, and is a frequent speaker at major software conferences. He is an avid soccer player, but loves even more working with small development teams, training them in OOAD and agile RUP, and then working with them side-by-side to deliver the right software faster than they ever thought possible. He can be reached at gkevans@evanetics.com. |
Rate this page
|  |