Skip to main content

Getting from use cases to code: Part II: Use Case Design

Gary Evans, Independent Object Technology Evangelist, Evanetics
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.

Summary:  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.

Date:  13 Aug 2004
Level:  Introductory
Activity:  2113 views

Illustration 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

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

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:

  1. Create use case realizations

  2. Describe interactions between design objects

  3. Simplify sequence diagrams using subsystems (optional)

  4. Describe persistence-related behavior

  5. 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:

  1. 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.

  2. Maintainability. Updates to software components must be made easily and centrally, with no distribution of business logic to browser platforms.

  3. 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.

  4. 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: 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

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

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)

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 for First Part of Reserve a Vehicle

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

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

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

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

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
StateSales
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:

MechanismPersistence
Design MechanismRDBMS -- 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 MechanismJDBC -- 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.


MechanismSecurity
Design MechanismAuthentication 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 MechanismUnique Customer Number (Awards ID number) as unique identifier; RDBMS index on Customer table.


MechanismLegacy 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 MechanismNone.

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.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Rational
ArticleID=93007
ArticleTitle=Getting from use cases to code: Part II: Use Case Design
publish-date=08132004
author1-email=
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers