Five-Step UML: OOAD for Short Attention Spans – Define, Refine, Assign

This article introduces the concepts of Five-Step UML, working from beginning to end. It introduces UML notation and goes into great detail. This article covers the first three of five steps. It is from chapter 2 of UML Applied A .NET Perspective, written by Martin L. Shoemaker (Apress, 2004; ISBN: 1590590872).

IN THIS CHAPTER, I’ll introduce you to Five-Step UML. We’ll work through the whole process from beginning to end, and along the way, I’ll be introducing all the UML notation that you’ll need to understand the relevant diagrams. I’ll also show you how the whole thing works from the point of view of .NET development.

By way of examples, I’ll be using lots of diagrams from the Kennel Management System case study, which was introduced at the end of the last chapter. I’m not going to show you everything in exhaustive detail at this stage, however, because we’ll be examining that case study more slowly throughout Part Two of the book. The aim of this chapter is simply to give you an overview of the whole process, a feel for how it all fits together, and a chance to get started with some modeling yourself.

So, I’ll begin this chapter with an overview of Five-Step UML to give you the big picture. Next we’ll focus in on the various steps. With each step, I’ll start by showing you the relevant UML notation that you’ll need, then walk through the process, and then we’ll look at some examples from the KMS.

Using a Process

OOAD and UML form a chicken-and-egg paradox: a good OOAD process requires a good notation; but when you study the notation, the most common question is, “Why would I do that?” where that means drawing a particular diagram to show a particular piece of your model. Often, the answer is, “Because we need it for this stage of the process.” The best way to teach UML effectively is to teach a software development process. And that’s when the groaning begins: Oh, no, not another process!

What’s Wrong with Process?

Why is it that programmers and process don’t mix well? Here are some of the common perceptions:

  • We’re too busy. Process means steps to follow, things to do. Well, we’re all overworked already. Who wants yet more work? We’ve got code to crank out!

  • It’s too much hassle. There are too many steps in a process. They just get in our way. The steps are too difficult or too poorly explained. We spent a lot of time learning to write code; now we have to learn all this other stuff, too? This is just make-work imposed on us by “the suits.” Let’s just crank out code!

  • It’s too complex. Look, we all know how to write code. Why are we making it all so complicated? Let’s just start cranking out the code.

  • It never works. Every so often, some pointy-haired manager type comes along with a “brilliant” plan that will “fix” everything. Then next year, there’s another plan, and another after that. And nothing ever really changes around here. So why waste time trying? We’re better off just cranking out code.

  • It’s too boring. Hey, code is fun! Process is work. Which would you rather do?

Whether these perceptions are true or not—and there’s some element of truth in each of them—they certainly make it harder to teach or learn process.

The Answer: Five-Step UML

In order to learn UML, then, we’ll start with Five-Step UML, a lightweight OOAD process that specifically addresses the common perceptions about process:

  • You’re not too busy. Five-Step UML is an aid to thinking about the problem and will give you focus and actually save you time. This isn’t about extra steps for you to follow; it’s about saving you steps by getting the design right in advance, so you spend less time rewriting code you’ve done wrong.

  • It’s not a lot of hassle. Although you can use a modeling tool, Five-Step UML can be performed with paper, Post-it notes, and a pencil. It doesn’t get in your way; it helps you to talk about the problem.

  • It’s not too complex. Five steps. Four diagram types (five, if you need Deployment Diagrams). Paper, Post-it notes, and pencil. How complex can it be?

  • It will work. Trust me. Or don’t trust me, and prove me wrong. But give it a try. Five-Step UML should be just enough process to show the benefits of UML, but not so much process as to drag you down.

  • It’s not boring, it’s fun! Well, that’s what I think anyway, and I have a lot of student feedback to support me. But you be the judge.

Now I don’t want to mislead you: Five-Step UML isn’t a full-featured OOAD process suitable for the development of complex systems. It has none of the management, testing, documentation, and review features that you expect from a complete process. It’s only a learning tool, a skeletal process suitable for learning UML, and not much more.


Or Is It . . . ?

I’m a fan of processes for complex system development. I think you should encourage your team to adopt more than Five-Step UML. But perhaps your team is particularly averse to process. Perhaps after looking at Five-Step UML, they may see it as the maximum process they’re willing to implement.

Is that bad? Not necessarily. According to Scott W. Ambler, “Agile Modeling (AM) is a chaordic, practice-based methodology for effective modeling and documentation of software-based systems.” 1 Ambler’s book describes lightweight modeling practices that might be characterized as “just enough”: just enough modeling and just enough process to get the job done. Five-Step UML is compatible with many of the Core Practices of Agile Modeling:

  • Apply the Right Artifacts

  • Create Several Models in Parallel

  • Iterate to Another Artifact

  • Model in Small Increments

  • Model with Others

  • Active Stakeholder Participation

  • Collective Ownership

  • Display Models Publicly

  • Create Simple Content

  • Depict Models Simply

  • Use the Simplest Tools

As Ambler says, “AM is not a prescriptive process. In other words, it doesn’t define detailed procedures for how to create a given type of model; instead it provides advice for how to be effective as a modeler.” Similarly, you might apply Five-Step UML as a modeling strategy inside of a larger process, whether it be a prescriptive process like the Unified Process or an agile process like Extreme Programming or Scrum.

1. Scott W. Ambler, Agile Modeling: Effective Practices for eXtreme Programming and the Unified Process (John Wiley & Sons, 2002) Chapter 2


Overview of Five-Step UML

Five-Step UML is also an example of what I call Model-Driven Development, in which the models become the central artifacts of the process, the central repository of all that is known about the system.

In this chapter, I’ll walk you through the complete process of Five-Step UML, but I won’t go into a lot of detail or tie together all the tasks outside of modeling, architecture, design, and coding. Later in the book, in Chapters 6 through 11, we’ll go though each step in more detail and see how you can tie the models to management, testing, and documentation tasks.

The Five Steps are as follows:

  1. Define. Identify the requirements of your system via Use Case Diagrams. Add other diagrams where they shed light on the use cases.

  2. Refine. Detail the steps in each requirement via scenarios captured in Activity Diagrams. Add other diagrams where they shed light on the activities.

  3. Assign. Use the Activity Diagrams to assign the steps to elements of your system.

  4. Design. Show the relations among the elements with Component Diagrams. Add other diagrams where they shed light on the components.

  5. Repeat/iterate/drill down/divide and conquer. Narrow the scope of your process to individual elements (designed with Class Diagrams); or expand it out to whole systems (designed with Deployment Diagrams). Add other diagrams wherever they help you understand the system. Repeat Steps 1 through 4 as appropriate for the current scope. Like Boehm’s Spiral development process, Evolutionary Development, and many other modern processes, Five-Step UML is an incremental, recursive approach.


“But What I Know Doesn’t Fit These Steps . . . ”

What happens when you learn something or know something that doesn’t “fit” your current step in Five-Step UML? Suppose your requirements tell you beyond a doubt that you’ll need a Web server, a DB server, and a firewall box? You can’t model that as a set of use cases.

In that case, read the first guideline in Chapter 3, Do What Works. These steps and the order they are in form a useful set of guidelines, not a rigid set of rules.

You can either read ahead in Five-Step UML to find the right way to handle the information; or you can simply write it down and set it aside, then revisit it until you find a step where you learn how to model the information.

Do What Works usually implies “update the model and draw the diagrams that fit what you know.” But right now, you’re just learning UML, so you can’t be expected to know how to model every piece of information. Just write it down and move along.

I’ll talk about this idea in more detail in the next chapter, along with a whole bunch of pragmatic guidelines to help you find your way through the modeling maze.


{mospagebreak title=Do It Yourself UML}

Do-It-Yourself UML

If you quickly flick through the rest of this chapter, it won’t take you long to figure out it’s a long one; and just sitting reading it from beginning to end could get a little tough, even with a big cup of coffee there to keep you going. And because we all know that the way to learn anything is to do it, not just to read about it, I recommend that you follow along with the exercises listed in this chapter, so you can start using UML right away.

Throughout this chapter, I’ll be examining each step in Five-Step UML; but before getting started, you should think about what kind of project you can use to get some practical UML experience.

Look for a Problem

You’ll need to select a problem domain which you’ll analyze and a solution which you’ll design with Five-Step UML. If you’re working by yourself, pick a domain in which you’re comfortable serving as customer, analyst, architect, and designer, but not one you know too well. If you’re working as a team, don’t pick a domain familiar to your team. Why shouldn’t you choose a familiar domain? Because experience shows that with a familiar domain, you’ll jump straight into designing

the system as it is when you should be analyzing the system as it should be. If you have no problem domain in mind, try one of these suggestions:

  • Hotel room scheduling and reservations

  • Flight scheduling and reservations

  • Rental car scheduling and reservations

  • Online travel service, including flight reservations, room reservations, car rental, and travel information (this will be less detailed than the preceding domains, but broader in scope).

  • University course scheduling and enrollment

  • Online banking

  • Online pizza ordering service (a popular choice with many programmers)

  • Package shipping and tracking

  • A calculator

  • A video game

  • An electronic diary

Select one person to serve as the customer (and final arbiter of what the customer wants). Call this person the customer rep. The rest of the team will act as analysts and designers.

With a Little Help from Your Friends

Five-Step UML is much more effective as a team exercise than as an individual exercise. The only student who has told me he didn’t learn from it was a conference attendee who chose to work by himself rather than join a group. UML is about communication, remember? Well, Five-Step UML is an exercise in team communication using UML. You’ll start to see the benefit when you draw the “perfect” picture, and your team members start tearing it apart, showing you what’s unclear, what you overlooked, and what you got wrong. And then, to make their points, they’ll have to produce even better pictures. I hate to use a management buzzword, but the synergism will astound you and sweep you up. Once you’ve done Five-Step UML with a good team, you may never want to design alone again. (This is the point of the Agile Modeling Core Practice, Model with Others.)

So I recommend you do the exercises in this chapter (and throughout the book) with a team of three to five people. Two is too few to generate enough disagreement; six or more can work, but some might have trouble getting at the paper. They don’t all have to have copies of this book (though it won’t break my heart if they do). They don’t even all have to be developers: managers, analysts, and end users should get a lot out of Steps 1 and 2; documenters and testers should get a lot out of Steps 1 through 4; and anyone who wants to learn more about the development process should learn something from all five steps. So rope in some coworkers, or friends, or relatives, or in-laws, or strangers off the street. For a team, these exercises should take about a day, if you try to do at least two of every diagram. Two diagrams make a good target. With the first diagram, you’re learning the process; with the second diagram, you’re practicing the process. If you try to analyze and design a whole system, this will take a lot longer.

{mospagebreak title=Step 1: Define}

Step 1: Define

Identify the requirements of your system via Use Case Diagrams. Add other diagrams where they shed light on the use cases.

In this step, you’ll describe what your system will do for each external user of the system, as well as what it will require from the users. These requirements shall be captured in Use Case Diagrams.

A Use Case Diagram is a way of depicting the interaction between your system and the outside world: your users, other systems, devices, etc. It’s a picture of the things your system will do—and more important, why it does them. At its core, a Use Case Diagram consists of three elements: actors, use cases, and communications.

First, I’ll make a quick tour of the UML notation that you need for these three elements, and show you how they fit together to form UML diagrams. After that, I’ll describe in more detail what needs to be done as part of this first step of Five-Step UML.

 


Isn’t That Just a Feature?

More than likely, you’ve used the use case concept in designing systems all along—perhaps even without recognizing it. As I discuss later, a Use Case Diagram is a way of discussing requirements in context. It’s that context—the actors and communications that relate to the use cases—that make them an expressive way of explaining and understanding a system. Actors and use cases are one example of how UML is unified. These concepts were formalized in Jacobson’s work on the Objectory process, and were adopted in UML because they filled a great need for a way to model requirements, not just structure and behavior.

 

UML Notation

In this section, we’ll look at the definitions and UML notation for actors, communications, use cases, and domain objects, and see how they all work together in Use Case Diagrams.

Actors

An actor represents any outside entity that interacts with your system. It may request services from your system; and it may perform services for your system. An actor can be a person; but it may also be another system, or perhaps a device such as a printer. An actor may even be a signal or event to which you must respond. From a component design perspective, you might model the clients of your component as actors, even though those are “the system” from the perspective of the designers of those components. (And conversely, of course, your component is an actor from their perspectives.)

In a Use Case Diagram, an actor usually appears as a stick figure icon (whether it represents a person or not). Other icons are allowed if they communicate the point of a diagram more clearly.

Actors: A .NET Perspective

If an actor is “any outside entity that interacts with your system,” then in .NET, that covers a lot of territory:

  • For a console or WinForms app, the actors include the user of the appli- cation, along with any services or controls from which the application gets information.

  • For an ASP.NET Web site, the actors include any viewers of the pages in the sites, as well as any servers from which the site gets information.

  • For a Web service, the actors include any other components that call the service, as well as any servers from which the site gets information.

Any person or system that requests that your .NET solution perform a task or does work as requested by your solution is an actor to your solution.

Communications

No, this isn’t the “communication” that I’ve been harping on since the start of this book. In this usage, a communication is a request or other sort of message between your system and your actors. While you are in the definition phase (Step 1), you don’t usually specify the mechanism by which the communication is transferred: it is enough to know that the transfer occurs. During design (Step 4), you should specify the mechanism in detail, either in the Use Case Diagram or in a Scenario Diagram. As you add detail, you may also describe what information (expressed as parameters) is included in the communication.

In a Use Case Diagram, a communication appears as a line or an arrow connecting an actor and a use case. The arrow is used to indicate the direction of a request for service: from an actor to the system, or from the system to an actor. Use a simple line to indicate an actor collaborating with the system without specifying where the request originates.

Communications: A .NET Perspective

Given the actors described earlier, some communications for .NET solutions include the following:

  • For a console or WinForms app, the user inputs—typing, button presses, mouse movements—which are all represented as events, any other events to which the app must respond, and any HTML or .NET Remoting calls that the app makes to other components

  • For an ASP.NET Web site or a Web Service, the HTML requests to the site, and (again) any HTML or .NET Remoting calls that the app makes to other components

Any message or event to which your .NET solution responds or which it sends can be represented as a communication.

Use Cases

A use case represents what your system does in response to a communication from an actor, and represents how your system carries out a requirement of that actor. It appears in a diagram as a simple descriptive phrase (an action, not an object); but within your model, it’s a placeholder to which you’ll attach additional documentation, more detailed diagrams, and anything you learn about the required behavior.

In a Use Case Diagram, a use case appears as an ellipse with a name inside or underneath. (Underneath is usually easier when you’re drawing diagrams by hand, because you don’t have to fit the ellipse to the name.)

Use Case Diagrams

Given these elements, then, a Use Case Diagram depicts the relationships between one or more actors and one or more use cases through one or more communications. Figure 2-1 is a Use Case Diagram that depicts the use cases required by the Pet Owner actor, from the Kennel Management System, introduced in the last chapter.


Figure 2-1.
  Pet Owner use cases

In this example, the actors are the Pet Owner, the Reservation Agent, the Care Giver, and the Accountant. They interact with the KMS in the following ways:

  • When the Pet Owner makes a reservation, the KMS will reserve a pen for the pet and then send the reservation to the Reservation Agent.

  • When the Pet Owner delivers the pet, the KMS will gather all information on the pet and then deliver the pet information and the pen assignment to the Care Giver.

  • When the Pet Owner arrives to pick up the pet, the KMS will call for the pet, sending the pet’s ID and pen assignment to the Care Giver.

  • When the Pet Owner pays the bill, the KMS will update the owner’s billing records and then send the new billing record to the Accountant.

Notice how, in analyzing the requirements of the Pet Owner actor, we’ve identified a number of other actors. You can thus use Use Case Diagrams as a means to discover additional actors that will use the system.

 


Who Needs Use Cases?

The first time you sit down to draw Use Case Diagrams, you may find yourself— how can I say this?—unimpressed. “Stick figures and bubbles. So what?” I know that was my reaction. It takes a little practice and experience to appreciate the benefit of use cases. After all, you might look at Figure 2-1 and feel that the same information could be conveyed in a simple functional spec, perhaps in bullet-list fashion:

  • The system shall reserve pens.

  • The system shall gather pet info.

  • The system shall fetch pets when called for.

  • The system shall update billing records when bills are paid.

So what do use cases tell you that you couldn’t get from a functional spec? Well, I found two great quotes that, together, really convey the benefit of use cases:

A functional specification can be said to answer the question, What is the system supposed to do? The use case strategy can be characterized by adding three words to the end of this question: for each user?

—The Three Amigos22

The focus on what the users need to do with the system is much more powerful than the traditional elicitation approach of asking users what they want the system to do.

—Karl E. Wiegers33

Who needs use cases? The end users! This is why I feel no Use Case Diagram is complete unless for every use case on it, the actor that initiates it is shown on the diagram and shown to be initiating it. The benefit of use cases is that they tie your model to well-defined user needs.

Does that mean I don’t believe in functional specs? Not at all! I like functional specs, for a very simple reason: text isn’t pictures. Not the most stunning of observations, but it’s important. The brain processes text through different channels and in different ways from pictures. That means that text and pictures will involve more brain cells than either would alone. More brain cells is a good thing. Furthermore, different reviewers and different stakeholders have different ways of thinking: some are more verbally oriented,

while others are more visually oriented. So by having both text (functional spec) and pictures (Use Case Diagrams), you can more fully involve more brains. More brains is also a good thing. In fact, use cases are more than just a pictorial strategy. Many use case practitioners document their use cases in very structured, very detailed text documents. This subject is beyond the scope of this book (for more information, see Wiegers,4 the Three Amigos,5 Schneider and Winters,6 and Cockburn7); but you could easily structure a functional spec not around bullet lists, but around use case docu ments. And depending on your UML tool, you might even be able to tie use case documents directly to use cases in the diagrams. But if time is short and you can only have diagrams or text, but not both, which one should you choose? I would go with Use Case Diagrams pretty much every time.

  1. Ivar Jacobson, Grady Booch, James Rumbaugh, The Unified Software Development Process (Addison-Wesley, 1999), p. 5

  2. Karl E. Wiegers, Software Requirements, Second Edition (Microsoft Press, 2003), p. 128

  3. Ibid., pp. 127–139

  4. Ivar Jacobson, Grady Booch, James Rumbaugh, The Unified Software Development Process (Addison-Wesley, 1999), p. 155–159

  5. Geri Schneider and Jason P. Winters, Applying Use Cases: A Practical Guide, Second Edition (Addison-Wesley, 2001), p. 27–66

  6. Alistair Cockburn, Writing Effective Use Cases (Addison-Wesley, 2000)

 

Domain Objects

Often as you model requirements, you’ll discover things that your system must maintain or represent: bills, schedules, reports, inventories, contacts, etc. You may want to indicate when and how these domain objects—objects within the problem domain—are modified or accessed by your system. You can do this by defining domain classes for these things, and then by adding the classes to existing Use Case Diagrams or by creating new Use Case Diagrams that focus on these classes. A class represents the operations and attributes of one or more objects within your system. An attribute is a characteristic that describes objects of the class, while an operation describes something an object of the class can do.  

In UML, a class appears as a rectangle broken into three sections. The top section identifies the name of the class, the middle section lists the attributes of the class, and the bottom section lists the operations of the class.

In Use Case Diagrams, you can add communications from use cases to the classes they affect, indicating how the system interacts with the objects, such as in Figure 2-2.


Figure 2-2.  Bill-related use cases

By adding Use Case Diagrams with classes, you can see how the actor requirements affect domain objects. This can help you to understand and prioritize requirements related to these domain objects.

Analyzing vs. Designing

When I begin adding classes to a Use Case Diagram, some students start getting nervous. “Wait a minute!” they say. “We’re gathering requirements, not designing the system. It’s too early to start talking about classes.”

And they’re absolutely right that it’s too soon to talk about design; but classes are not just a design issue: they’re a way of categorizing the things around us, whether in the code or in the real world. Real-world things can be categorized. Real-world things can be described. Real-world things can do things. From the perspective of a model, real-world things and software things are very similar in nature, and can be modeled with a very similar notation.

So here, you’re using classes and objects to represent the problem domain, not the code. At design and implementation time, you’ll decide which of these real-world classes must become classes in the software, as well as which additional classes are needed to support the system operations.

If you’re still troubled by classes on a Use Case Diagram, consider that actors were originally modeled in UML as a special sort of class. After all, actors have attributes (names, IDs, etc.) and can perform operations (authorize actions, acknowledge tasks, etc.). So in essence, when there’s an actor on a Use Case Diagram, there’s a type of class on the diagram. Domain object classes are just another way of describing the interaction of the system with the problem domain.

And if you’re still unconvinced, read the first guideline in Chapter 3, Do What Works. If classes help you to understand the point of a Use Case Diagram, then classes are a good thing; and if not having classes makes the diagram less clear, then classes are a must.

Exercise 201: Define Your System with Use Case Diagrams:
Taking the problem domain you’ve chosen, work with your team through each of the processes described next for Step 1 of Five-Step UML. Identify all the actors and domain objects in your problem domain, and use these to uncover and document your requirements as Use Case Diagrams.

{mospagebreak title=Step 1 Process in Detail}

Step 1: Process in Detail

You should begin Step 1 by identifying your actors and domain objects (this list doesn’t have to be perfect—you can always come back to amend it later on). Next, for each actor you’ve identified, you should list all the use cases initiated by that actor, and check whether any other actors are involved in those use cases. You can then look at your collection of use cases and see which domain objects are necessary for them.

Let’s look at this process in more detail.

Identify Actors

When modeling a complex system, you can identify actors for your system in many ways: end-user interviews, marketing studies, requirements documents, etc. This is discussed in more detail in Chapter 6.

If you and your team are working through Step 1 as an exercise, then you’re going to have to rely on yourselves to define all of your requirements, which you can do by brainstorming together to identify useful actors. Think about what actors might either request behavior from your system or provide services to your system.

Don’t worry if you can’t think of every possible actor: you can use your known actors to identify unknown actors. Also, don’t worry if you may have extraneous actors: you can use your Use Case Diagrams to identify the relevant actors. These are candidate actors: you’ll revise the list as you go along. Put all actors you identify into an Actor List.

Remember, if the search for actors gets hung up on any question, your customer rep is always the final arbiter.


Brainstorming 101

In case you’ve never been in a brainstorming session, here are the basics of

“formal” brainstorming that you’ll need for the exercises in this chapter:

  1. The goal of brainstorming is to gather a large number of potentially significant ideas upon which you’ll build.

  2. One person must act in the role of recorder, ensuring that all ideas are captured. No other formal roles are defined. Everyone is equal in a brainstorming session.

  3. No idea can be rejected! During brainstorming, no idea is impossible, outrageous, irrelevant, or impractical. Brainstorming is about spanning the range of ideas, not about defining the problem. Filtering and refinement will come later.

 

In Chapter 6, we’ll look in more detail about techniques you can use to identify your domain objects, but for now you can brainstorm to identify candidate domain objects, just as you did for actors. A good place to start is to think about the sort of information that is important to your candidate actors.

Some useful categories of domain objects are

  • Reports

  • Schedules

  • Appointments

  • Tasks

  • Purchase Orders

  • Work Orders

  • Invoices

  • Calendars

  • Customer Records

  • Employee Records

  • Tax Records

  • Memos

  • Assignments

  • Contracts

  • Inventories

  • Inventory Items

  • Requisitions

  • Messages

Again, these domain objects should depict the real-world entities, not their software representations. Don’t worry if you can’t think of every possible domain object: you can use your actors and Use Case Diagrams to identify more domain objects. Put all the objects you identify into a Domain Object List.

Remember, if the search for domain objects gets hung up on any question, your customer rep is always the final arbiter.

Pick an Actor

Select the actor that is most likely to use your system. When in doubt, then Customer is usually a good bet, because most systems have some sort of customer, who is the ultimate end user of the services provided.


“That’s Not What We Call It. . . ”

Your customer rep may tell you that customers are referred to as “clients” (or “patrons,” or “guests,” etc.). That’s great! Learn to speak the customer’s language. We all know (or are supposed to know) that code-and-fix is a bad thing; but design-and-fix is a good thing. Never be afraid to put something on a page that someone may dispute. The sooner the dispute is out in the open, the sooner you’ll resolve it.

You have to be careful, in fact, of the opposite problem: customers who are afraid to tell you that you’re wrong. Whether in an exercise or in real requirements gathering, keep the tone loose and comfortable. All participants have to feel free to speak their minds and raise their concerns.

 

Identify Requirements for the Actor

Document the actor’s requirements as use cases in a Use Case Diagram for the chosen actor.

Note that if you’re using paper and pencil (rather than a modeling tool), you may find it extremely helpful to draw your actors and use cases and even the communications on Post-it notes, so that you may rearrange the diagrams as you refine your ideas. Add each use case to a Use Case List.

Examine the use cases in the diagram. Do any of them affect domain objects? If the diagram isn’t too complex, add the domain objects affected, along with any communications to those objects. Do not add the objects if the diagram is harder to read as a result. You’ll have a chance to address domain objects later.

Identify Participating Actors

For each use case for the chosen actor, identify any new or existing actors that also participate in the use case. Add any new actors to the Actor List.

Repeat for Each Remaining Actor

Check off the chosen actor in the Actor List. Then pick another actor, and draw the Use Case Diagram for that actor. Repeat until all requirements have been diagrammed for all actors. If you find an actor that neither requires any behavior from the system nor provides any services to the system, cross that actor off the Actor List.

If you’re working through this process as an exercise, I recommend that you do at least two actor-centered Use Case Diagrams for practice, and more if you wish.

Pick a Domain Object

Select a domain object from your Domain Object List, and start a new Use Case Diagram centered on that object.

Identify Requirements That Relate to the Domain Object

Determine which use cases affect that domain object, and add them to the diagram. Then add the communications from the use cases to the object, and label the communications to describe the changes made by the use cases. Then add the actors that initiate each use case. (Don’t add other participating actors, because the diagram will likely become too cluttered.)

Repeat for Each Remaining Domain Object

Check off the chosen domain object in the Domain Object List. Then pick another domain object, and draw the Use Case Diagram for that object. Repeat until all modifications have been diagrammed for all domain objects. If you find a domain object that is never modified by any known use case, cross that object off the Domain Object List.

If you’re working through this process as an exercise, I recommend that you do at least two object-centered Use Case Diagrams for practice, and more if you wish.

Example

I won’t run through this first step of the process in full detail for my Kennel Management System here, because we’ll be looking at that in Chapter 6. But let’s look at a couple of diagrams from this, just to get a feel for how it all works.

For example, one of the actors identified for the Kennel Management System is the Reservation Agent and Figure 2-3 shows the Use Case Diagram for this particular actor.


Figure 2-3.  Reservation Agent use cases

Note how, for the sake of completeness, I showed the Reserve a Pen use case in which the Reservation Agent participates, rather than initiates.

If you find that including all the use cases in which an actor participates makes your diagram too cluttered, then you could opt to only show the use cases initiated by a given actor.

Figure 2-4 is another Use Case Diagram from the Kennel Management System, but this time we’re focusing on one of the domain objects that has been identified, Pen.


Figure 2-4.  Pen use cases


TIP: Don’t worry if any of this still seems confusing. I’ll be walking through this first step of Five-Step UML in a lot more detail in Chapter 6, where you can see how I go about defining all of the requirements of the Kennel Management System.

So that’s it! By the time you’ve finished this first step, you should have a complete set of Use Case Diagrams. You may need to modify these later as you discover more about your model, but for now it’s time to move on to Step 2 of the process.

{mospagebreak title=Step 2: Refine}

Step 2: Refine

Detail the steps in each requirement via scenarios captured in Activity Diagrams. Add other diagrams where they shed light on the activities.

In this step, you’ll describe in more detail what your system will do within each use case. Any given use case will have at least one scenario that describes a particular way the use case may be carried out. This is the Primary Scenario (or less formally, the Happy Path), and reflects what happens in the normal, expected case. If there are decisions or exceptions or errors that must be handled within the use case, these will dictate Alternate Scenarios (or Exception Paths). The Primary and Alternate Scenarios shall be captured in an Activity Diagram.

An Activity Diagram is a way of depicting a set of steps of operation within your system, and is often attached to a use case (as you’ll do in Five-Step UML). It has much in common with old-fashioned flowcharts—in essence, the Activity Diagram notation is a simplification of the flowchart notation—and thus should be comprehensible to a very wide audience. I like to call Activity Diagrams “the revenge of the flowchart”; in my more cynical moments, I wonder if teaching UML is a penance I must serve for having such disdain for flowcharts as a younger developer. But in fact, Activity Diagrams both supplement and simplify the old-fashioned flowchart notation, allowing for more useful diagrams than anything I saw in my youth.

UML Notation

At its core, a simple Activity Diagram consists of eight elements: initial states, terminal states, activities, transitions, branches, merges, forks, and joins.

Initial States

An initial state denotes where the scenarios in your Activity Diagram begin. Think of it as the entry point to your diagram. There should be exactly one initial state in a well-formed Activity Diagram: if there were no initial state or multiple initial states, readers of your diagram would not know where to look first.

In an Activity Diagram, an initial state appears as a solid black dot.

Terminal States

A terminal state denotes the completion of the scenarios in your Activity Diagram. This is the point to which the diagram leads. There should be zero or one in a well-formed Activity Diagram: one if the scenarios have a definite end, zero if the scenarios cycle repeatedly with no defined termination. This rule is often broken, because it can be far less cluttered to have multiple terminal states in a diagram than to have arrows that snake all over the page to reach a single terminal state.

In an Activity Diagram, a terminal state appears as a solid black dot in a larger circle. (Think of it as the “target” of the diagram, to which all paths lead.)

Activities

An activity (or more formally, an activity state) depicts an action taken by your system. It’s a brief description that often represents more detailed actions underneath. (Later, as you refine your design further, you’ll create more detailed activities that approach the level of code.)

In an Activity Diagram, an activity appears as a rectangle with semicircular ends. (I call this the “capsule shape,” because it resembles a cold capsule. Others call it the “hotdog shape” for similar reasons.)

 


Why “States”?

Why are activities also called “activity states”? Why “initial states” and “terminal states”? Well, it’s time for a little history lesson.

Activity Diagrams are a fairly recent addition to UML; but before there were Activity Diagrams, there were Statechart Diagrams. A Statechart Diagram depicts states of the system or part of the system, along with how events cause changes in those states. They’re a very powerful tool, especially in modeling real-time systems and mechanical interfaces.

Now hard-core state modelers are a strange bunch, at first. They will get quite adamant that Print Invoice isn’t a state, but Print ing Invoice is. While they can get a bit pedantic about this, their point is fundamentally correct: a state isn’t something a system does; it is a description of a system, and may include a description of what the system is doing. States are also (potentially) interrupt ible by events. If you don’t keep these ideas in mind, you may create Statechart Diagrams that are more confusing than helpful.

But less hard-core state modelers—and especially people who had never seen Statechart Diagrams before, and didn’t get the point—sat down and used State- chart Diagrams to build glorified flowcharts. UML already had Sequence Diagrams, which could be used like flowcharts in some ways; but it was clear that a flowchart-like diagram was needed by many modelers.

So Activity Diagrams were added to UML; but they were first introduced as a modification of the Statechart Diagram. You still see some of this legacy in the nomenclature.

Expect to see some minor changes to Activity Diagrams in UML 2.0. One of these changes will be to formally separate Activity Diagrams from Statechart Diagrams. There will also be changes to better support business modeling using Activity Diagrams.

Transitions

A transition represents the flow of control in your system from one activity to another. You may also create transitions from an initial state to an activity or from an activity to a terminal state; and (as you’ll see later) you may also create transitions to and from branches, merges, forks, and joins. The transitions form the “flow” of your scenarios in terms of steps being carried out. They may also indicate events that cause the system to stop one activity and begin another. For example, an activity of Poll for Input may end when an Input Received transition transfers control to a Process Input activity.

In an Activity Diagram, a transition appears as an arrow indicating the flow of control. It may optionally include a label that denotes the event that causes the transition; and (as you’ll see in the next section) it may also include a guard condition enclosed in square brackets.

Branches

A branch represents a decision in your system, a point where you must select exactly one of multiple possible transitions to follow. Each transition leading from the branch must have a guard condition, an expression which evaluates to true or false; and in a well-formed Activity Diagram, exactly one guard condition may evaluate to true each time control reaches a particular branch.


In an Activity Diagram, a branch appears as a diamond with one or more transitions entering it and two or more transitions leaving it (each with a guard condition).

Merges

A merge is the opposite of a branch: a place where two or more alternate flows of control rejoin and continue as a single flow. You may see diagrams in which a merge is also a branch. For example, the start of a loop is often modeled as a branch (because flow either enters the loop body or skips it) and as a merge (because you can enter the loop start from before the loop or by returning to the start of the loop).

In an Activity Diagram, a merge appears as a diamond with two or more transitions entering it and one or more transitions leaving it.

Forks

A fork is a way to show multiple activities that can occur in any order, or even simultaneously. It represents a single flow that splits into multiple flows, such as multithreaded programs or multiple processes.

In an Activity Diagram, a fork appears as a thick horizontal or vertical line with one transition entering it and two or more transitions leaving it. The outgoing transitions from a fork are commonly called threads.


Threads vs. Threads

If you come to UML from a parallel processing background, “threads” may imply “multithreaded programming” to you, since that’s a common technology for implementing parallel behavior. This is one example of code you might model with UML threads; but threads in UML are more general than that. A thread simply indicates a subflow of control that begins at a fork, ends at a join, and may occur before, after, or simultaneously with other threads of control.

During Step 2 of Five-Step UML, the refining stage, you’ll seldom need to think about forks (or about joins, as described next). Unless the requirements specifically state that certain activities must occur simultaneously, forking is more of an implementation issue that may only confuse the gathering of requirements. During design (Step 4), forks and joins will be useful ways to depict simultaneous activities.

Joins

A join is the opposite of a fork: a place where two or more threads rejoin to form a single flow. It represents the completion of all activities within each of the threads.

In an Activity Diagram, a join appears as a thick horizontal or vertical line with two or more threads entering it and one transition leaving it.

Activity Diagrams

Given these elements, then, an Activity Diagram depicts the transitions between activities, branches, merges, forks, and joins that collectively depict the playing out of one or more scenarios. Figure 2-5 is an Activity Diagram that depicts the scenarios within the Gather Pet Info use case from the KMS case study.


Figure 2-5.  Activity Diagram for Get Pet Info use case

In this example, you can see four scenarios:

  1. The pet owner and the pet both have records in the system. In this scenario (the Primary Scenario), you get the owner’s name, look up the owner’s record, get the pet’s name, look up the pet’s record, and then get the pet’s vital stats.

  2. The pet owner has a new pet with no record in the system. In this Alternate Scenario, you get the owner’s name, look up the owner’s record, get the pet’s name, look up the pet’s record, fail to find a record for the pet, add a new record for the pet, and then get the pet’s vital stats.

  3. The pet has a new pet owner with no record in the system. In this Alternate Scenario, you get the owner’s name, look up the owner’s record, fail to find a record for the pet owner, add a new record for the pet owner, get the pet’s name, look up the pet’s record, and then get the pet’s vital stats.

  4. A new pet owner brings in a new pet. In this Alternate Scenario, you get the owner’s name, look up the owner’s record, fail to find a record for the pet owner, add a new record for the pet owner, get the pet’s name, look up the pet’s record, fail to find a record for the pet, add a new record for the pet, and then get the pet’s vital stats.

Subactivity States

So far, I’ve only identified three Alternate Scenarios in Figure 2-5, and already it is quite complex. Imagine how much worse it could get with many more Alternate Scenarios. If you want to communicate with this diagram, you might want to simplify it. (Note the emphasis on might: this is an example, not necessarily the only solution.)

You can simplify the diagram by using subactivity states. In an Activity Diagram, a subactivity state is an activity that contains a more detailed Activity Diagram. This contained diagram can be depicted on the main diagram (though that seldom simplifies the picture), or it can be shown on a separate page (for a paper model), or it can be placed inside the activity (for an electronic model).

So Figure 2-5 might be simplified as in Figure 2-6, where the new states, Get Pet and Get Owner, are subactivity states.


Figure 2-6 Activity Diagram for Get Pet Info use case (with subactivity states)

Then the Activity Diagrams for the Get Owner and Get Pet subactivity states might be depicted as in Figures 2-7 and 2-8.


Figure 2-7.
  Activity Diagram for Get Owner


Figure 2-8.
  Activity Diagram for Get Pet

Note how each contained Activity Diagram has its own initial and terminal state, just as the primary diagram does.

In later examples in this chapter, we’ll work from Figure 2-5, not from Figures 2-6 to 2-8. Figure 2-5 makes a better example to build upon. But I think you can make a good case that the latter diagrams are easier to comprehend.


A Better Approach?

As a rule, it’s better to identify the subactivity states in advance, rather than defining them after the fact. It’s often easier to draw the diagrams this way (especially with some UML tools), and you do less rework. So I encourage you: if you foresee a need for subactivity states, add them in from the start. If you can do that, more power to you. You’re a “big picture” thinker with a lot of foresight. Me? I’m a detail thinker, and I almost never can foresee the need for subactivity states. Sometimes, I wish I could.

There is one exception to my lack of foresight: I have learned from hard experience that it’s pretty much always easier to understand forks and joins and threads if the body of each thread is a single activity. That usually means it’s a subactivity state.

Exercise 202: Refine Your System Definition with Activity Diagrams:
Now that you have an idea of how Activity Diagrams are put together, you can work with your team through Step 2 of Five-Step UML. Taking the use cases you created in the previous exercise (201) as a starting point, follow through the process described next to create your Activity Diagrams.

{mospagebreak title=Step 2 Process in Detail}

Step 2: Process in Detail

In Step 2 of Five-Step UML, you need to step through all of the use cases that you documented in Step 1, and examine them to determine the various scenarios of each one. You can then define these scenarios using Activity Diagrams, showing what happens at each stage and how different paths may be found through the use case. If diagrams become too large, complex detail can be hidden in subactivity states.

Let’s look at this process in more detail.

Pick a Use Case

To get started, just select any use case from the Use Case List. There’s no particular order you need to follow, since you’ll analyze every use case eventually.

Find the Scenarios

To work out your scenarios, you can use interviews with the end users, requirements documents, and brainstorming techniques. Ask yourself what should happen in the use case, and what else could occur. Make a Scenario List with some likely scenarios for the chosen use case. When you have finished, select one scenario as the most common or most trouble free or most desirable. This will be your Primary Scenario for the chosen use case.

Draw the Happy Path

Create an Activity Diagram that depicts the Primary Scenario. Break the scenario down into the business rule steps that you understand at this stage. You’re not trying to completely design the solution for this use case yet; rather, you’re trying to verify that you understand the steps that will satisfy the requirements of the actors. If you feel like you’re practically writing code, you’re getting too detailed!

Draw the Exception Paths

For each activity in the diagram, think about what could go wrong. At this stage, don’t worry about implementation exceptions (e.g., “What happens if the hard drive fills up?”). Instead, worry about exceptions within the problem domain and the business rules (e.g., “What happens if the user isn’t authorized to use the system?”) Add a branch after each activity that might result in an exception; then add transitions, guard conditions, and activities to handle each exception. Also add merges to reflect the flow rejoining where appropriate.

At about this point, you should be very grateful if you’re using a modeling tool or Post-it notes, and very sorry if you’re using only paper and pencil. Rearranging hand-drawn diagrams is hard work, and it’s only going to get worse in Step 3.

Check off each scenario in the Scenario List for the chosen use case as you add it to the Activity Diagram. Repeat until you’re comfortable that you have addressed the major issues and scenarios in the chosen use case. (Don’t cross off unrealized scenarios: they may be too detailed for this scope, and you may still have to handle them when you get into implementation design.)

Look for Parallel Behavior

Examine the Activity Diagram. Are there any activities that must occur simultaneously? If so, add forks and joins and threads that encompass these activities as appropriate. Don’t add threads gratuitously—especially not during analysis!— but be sure that you have them where parallel behavior is required.

Consider Subactivity States and Additional Diagrams

If your diagram is getting complex, consider adding some subactivity states and some contained diagrams. In particular, if you have forks and joins and threads, consider moving the entire contents of each thread into a subactivity state that represents that thread. Like threads, don’t add subactivity states gratuitously: multiple diagrams add a comprehension burden that may be worse than one slightly complex diagram. Only add subactivity states where they simplify the message.

Repeat for Each Remaining Use Case

Check off the chosen use case in the Use Case List. Then pick another use case, and draw the Activity Diagram for that use case. Repeat until all major scenarios have been diagrammed for all use cases.

If you’re working through this process as an exercise, I recommend that you do at least two Activity Diagrams for practice, and more if you wish.

Example

As an example, Figure 2-9 is another Activity Diagram from the Kennel Management System, based on the Locate Pet use case discovered in Step 1.


Figure 2-9.  Activity Diagram for Locate Pet use case


TIP To learn more about developing Activity Diagrams, see Chapter 7.

{mospagebreak title=Step 3: Assign}

Step 3: Assign

Use the Activity Diagrams to assign the steps to elements of your system.

In this step, you’ll assign your activities (from the previous step) to elements of your system. Because most development today is component-based in some fashion (particularly in the .NET environment), assume that the elements in this case shall be components, interfaces exposed by those components, and user

interfaces provided by those components. (In Step 5, you’ll zoom in to elements that are classes within a component, or out to elements that are nodes in a distributed architecture.) This step forms the bridge between requirements and architecture, as defined by interfaces, user interfaces, and components. You’ll express the activity assignments by adding one new concept to Activity Diagrams: swimlanes.

Swimlanes are so new, in fact, that not all UML tools support them, and there is a wide range of opinions on “correct” and “incorrect” ways to use them. As always, my opinion is if you’re communicating, you’re using UML correctly.

UML Notation: Swimlanes

Swimlanes are an extension to Activity Diagrams to depict which elements of your system are responsible for which behavior. You simply divide an Activity Diagram into vertical swimlanes, each labeled with the name of the interface or user interface it represents; and then you drag each activity into the swimlane for the interface or user interface that will be responsible for it. Also drag branches, merges, forks, and joins into swimlanes as appropriate, and maintain the transitions between elements. The activities assigned to a given interface may become operations of that interface as the design progresses.

For example, Figure 2-10 is basically the diagram in Figure 2-5 with swim-lanes added.


Figure 2-10.  Activity Diagram for Get Pet Info use case (with swimlanes)

Here, I’ve added four swimlanes:

  1. Pet Owner. This swimlane represents the Pet Owner actor that initiates the use case for this Activity Diagram. In this example, the Pet Owner is only kicking off the use case. In other diagrams, the initiating actor may take actions within the use case. (See the sidebar “But the Owner Database Is Calling the Check In UI” for an example of this.)

  2. Check In UI. This swimlane represents the user interface with which the Pet Owner interacts.

  3. Owner Info. This swimlane represents an interface for storing information about Pet Owners.

  4. Pet Info. This swimlane represents an interface for storing information about Pets.

The Activity Diagram in Figure 2-10 may look confusing to you. The Check In UI calls (i.e., transfers control to) the Owner Info swimlane, which makes sense; but then the Owner Info swimlane appears to call the Check In UI, which makes no sense at all. The flow of steps made sense before you added swimlanes, and is still correct; but with swimlanes added, the implications may be puzzling.

The confusion arises because transitions in an Activity Diagram aren’t really “calls” in the sense of calling a function: they include any way in which control flows from one activity to another: jumps, calls, returns, interrupts, event handlers, etc. A transition usually connotes a simple jump, with no knowledge of from whence the jump came.


Stereotypes

Stereotypes are discussed in detail in Chapter 3; but for now, you only need to know three things:

  1. A stereotype is a way to extend the UML to express design concepts it doesn’t already contain, and may be applied to any existing element of a model.

  2. A stereotype can appear in a diagram inside guillemets (« ») or double angle brackets.

  3. UML uses some predefined stereotypes, but you can also create your own custom stereotypes.

 

We can change this, however, by adding some custom stereotypes of transition (see the sidebar “Stereotypes” for more information on stereotypes). So we’ll add three custom stereotypes for transitions:

  1. «invoke». This stereotype on a transition indicates that, in the normal course of activity A, flow transfers to activity B via a function call or similar mechanism. Then, when activity B is complete, flow returns to activity A, without the need of a return transition.

  2. «interrupt». This stereotype on a transition indicates that, without regard to the normal course of activity A, flow may transfer to activity B via an interrupt or event or similar mechanism. Then, when activity B is complete, flow returns to activity A as if it had never been interrupted.

  3. «UI». This stereotype on a transition indicates that a user performs an operation via a user interface.

It may also be useful to use terminal states to indicate the end of a call or interrupt, with a stereotype of «return». (Does this make an Activity Diagram not well formed, since it has multiple terminal states? Absolutely! But if my choices are a poorly formed diagram that communicates and a well-formed diagram that doesn’t, which do you expect me to choose?)

So examining this use case again, it seems likely that the actual flow will be driven by the Pet Owner. We can add new activities and transitions to reflect this, as shown in Figure 2-11.


Figure 2-11.  Activity Diagram for Get Pet Info use case (with <<UI>> and <<invoke>> transitions)

Now the Pet Owner takes three actions, and the KMS responds to each.

The Activity Diagram in Figure 2-11 reveals a missing step in the original business rules (as expressed in Figure 2-5): the pet’s vital stats are never explicitly stored. In the original diagram, we simply assumed that if we gather the vital stats, we store them. But in Figure 2-11, where we explicitly create the owner and pet records, it looks more jarring that we don’t store the vital stats.

This should not surprise you. As you try to define an architecture to fit the requirements, you inevitably discover “implied” requirements; and you likely have to add implied activities and implied swimlanes to support these implied requirements. These implied elements weren’t in the original use cases and business rules because of what Joel Spolsky calls “The Iceberg Secret”:

You know how an iceberg is 90% underwater? Well, most software is like that too—there’s a pretty user interface that takes about 10% of the work, and then 90% of the programming work is under the covers. And if you take into account the fact that about half of your time is spent fixing bugs, the UI only takes 5% of the work. And if you limit yourself to the visual part of the UI, the pixels, what you would see in PowerPoint, now we’re talking less than 1%. That’s not the secret. The secret is that People Who Aren’t Programmers Do Not Understand This. 8

Feel lucky if your users give you concise, logical business rules that get you started on defining Primary and Alternate Scenarios. Many can’t go far beyond describing the user interface, because that “surface layer” is all they interact with. The whole rich structure that underlies that surface is beyond invisible to them: for the most part, it just doesn’t exist. So you should expect to find implicit requirements in the business rules; and you should expect to find back-end activities and interfaces that are necessary to support both explicit and implicit requirements. In general, you should expect this architectural assignment stage to be a complex process that raises a lot of questions. Learn to expect these holes in the business rules.

When you find these holes, you patch them, right? Not a chance! Oh, if you’re doing Five-Step UML as an exercise, patch away! But if you’re following a process for fitting architecture to requirements and you find a hole in the requirements, you have to go back to the source of your requirements to find out the correct way to patch the hole. Take nothing for granted, even something as obvious as “If we’re gathering data, we want to store it. Duh!”

8. Joel Spolsky, “The Iceberg Secret, Revealed,” from the Joel on Software Web log (http://www.joelonsoftware.com/articles/fog0000000356.html). Besides maintaining a popular Web log on software development issues, Joel is the author of User Interface Design for Programmers (Apress, 2001), a great book to get you thinking like the user of your application.

Architects and developers aren’t the source of requirements, and our instincts aren’t to be trusted when it comes to requirements, for multiple reasons:

  • You don’t know the problem domain. OK, in rare cases, you know the problem well enough, but don’t trust your judgment in this respect.

  • You’re weird. I’m sorry to have to break this to you, but you’re weird. Oh, not in the purple-hair-pierced-eyebrow sense, nor in the never-wear- shoes-and-it’s-all-we-can-do-to-get-you-to-wear-clothes sense (though I’ve known developers of both kinds, and they’ve been fine members of the team). No, you’re weird in the brighter-than-average-and-better-at- abstraction sense. It’s an inevitable consequence of our profession: we select for those traits; and if you don’t have those traits, you don’t last long as a developer. All high-skill jobs select for weird people, different people from the norm; and then the jobs usually give those people a chance to practice skills that the average person never practices. Selecting for weird is why most NBA stars are much taller than the population average; and practicing niche skills is why they can make long-distance shots and complex defenses look easy. If you’re a developer, you likely can manage more complex abstractions and keep more details straight in your head; and you likely have practiced studying and implementing abstractions far more complex than your average user ever experiences. So you are not the best judge of what is simple and comprehensible and practical.

  • Your users are weird, often for similar reasons: they work in a specialized domain that selects for certain mentalities. One of my recent clients was an organization that does postmortem studies on brain physiology and genetic traits for studies of mental illness. These people were no dummies! They learned my field far faster than I learned theirs. Don’t assume your users are “average.”

So if you’re not going to patch holes, what should you do? Suggest patches. Analyze your suggestions, and prepare descriptions of the implications of and trade-offs from particular patches. Draw the diagrams of how you understand things now and of how you think things might work. You may not know what the users need, but you’re good at knowing the implications of particular architectures and implementations. So go to your users with an explanation of what the hole is, along with one or more suggested patches. Explain the problem, and show them the pictures. The worst thing that could happen is they’ll accept one of your suggestions, and you’ll look like a genius for foreseeing their needs. The best thing that could happen is that they’ll reject your suggestions and explain why. You and they can then work out a more useful patch; and in the process of suggesting the wrong patches, you learned something new about the requirements. That’s always a good thing.

In the case of our swimlaned Activity Diagram (Figure 2-11), the obvious patch is to have the Get Pet Vital Stats activity write this to some sort of vital stat storage system; but let’s assume for now our architecture team want to hide the vital stat details behind the Pet Info mechanism, since vital stats are associated with pets. So we’ll add an activity to the Pet Info interface, Write Vital Stats, but we won’t worry too much about how that activity manages the process of writing out the data. The result is shown in Figure 2-12.


Figure 2-12.  Activity Diagram for Get Pet Info use case (architectural view)

Note the other change that we’ve made to the diagram here: we’ve simplified it as discussed in the last section (Step 2) by adding subactivity states for Get or Add Owner and Get or Add Pet. I’ll not bother including the separate Activity Diagrams for these two subactivity states here, as the logic is essentially the same as that for the subactivity states we examined in the last section.

But to discuss the architecture with end users, I might retain the more complex diagram, rather than hide details inside subactivity states, so that I can demonstrate to them that their business rules are covered by the system. This is one of many reasons to maintain separate models and separate diagrams. It’s also a good reason to not change or throw away old diagrams. (And if the new diagram is really difficult to comprehend, maybe you’ve gone too far. This is why I appreciate a good undo feature in a UML tool.)

Another variation on this diagram is shown in Figure 2-13. Here, we explicitly show how the Write Vital Stats activity uses another interface, Vital Stats Info, to perform its task.


Figure 2-13.  Activity Diagram for Get Pet Info use case (alternate architectural view)

Is this the best solution? That depends largely on your perspective, for example, on whether you consider the Vital Stats Info interface an implementation detail not needed at this stage. Similarly, we can ask ourselves whether we should explicitly show all of the activity states.

My students have learned that if you ask me “ A or B ?” my answer is usually “Yes” or “ C.” This is a case where my answer is “Yes”: the diagrams are all correct, but have different purposes. I believe a model may contain multiple diagrams of a given issue, reflecting different stakeholder perspectives and concerns.

Swimlaned Activity Diagrams vs. Sequence Diagrams

If you’ve studied or worked with UML before, you may find that Activity Diagrams with swimlanes bear a strong resemblance to UML Sequence Diagrams—especially when I add in the «invoke» stereotype. For instance, Figure 2-13 could be redrawn as a Sequence Diagram, as shown in Figure 2-14.


Figure 2-14.  Sequence Diagram for Get Pet Info use case

This is the traditional way to model this sort of interaction in UML; but in practice, Sequence Diagrams aren’t very effective for showing complex logic. They’re really a rather linear form of a diagram, and complex logic isn’t linear: it has branches and loops, and it has drill-down into more detailed behavior. This logic is difficult to convey with Sequence Diagrams.

Activity Diagrams, meanwhile, are explicitly designed for showing complex logic, and for showing drill-down with subactivity states; and with the addition of swimlanes, they show interactions very much as you can show them in Sequence Diagrams.

So though some practitioners frown on using Activity Diagrams with swim-lanes where you “ought to” use Sequence Diagrams—arguing that these diagrams should be reserved strictly for business logic—I’ll stick with a pragmatic approach: the Activity Diagrams work, and it’s easy with a tool like XDE to go from business rules expressed as Activity Diagrams to interaction diagrams expressed as Activity Diagrams with swimlanes. If you find it practical to use Sequence Diagrams instead, feel free to do so.

Activity and Sequence Diagrams in UML 2.0, Redux

Perhaps one of the larger changes to Activity Diagrams in UML 2.0 isn’t a change to Activity Diagrams at all: it’s a change to Sequence Diagrams. The standards committee is adding the concept of frames, which are roughly equivalent to subactivity states in Activity Diagrams, and which can also be conditional and iterated. With frames, most of the problems with complex logic in Sequence Diagrams have been resolved.

So there may be a lot less reason to use Activity Diagrams in place of Sequence Diagrams, as I commonly do. Some concepts (like «invoke») are modeled directly in Sequence Diagrams, but for these you must create stereotypes in Activity Diagrams. Plus there’s a nostalgia factor: Sequence Diagrams were the first UML diagrams in which I really saw a benefit of drawing them. So I’m hopeful that frames will allow me to model a lot more concepts in Sequence Diagrams in situations where I currently use Activity Diagrams. I may still find, though, that the tools make it easier to use Activity Diagrams for these purposes.

Swimlanes: A .NET Perspective

Looking ahead, you can start to think of these swimlanes in terms of the .NET technologies they represent. A user interface swimlane such as the Check In UI should represent one of the common .NET user interface technologies:

  • Console I/O. .NET supports a rich console API, far better than in any version of Windows. In a console app, the system prints messages, and the user types responses.

  • ASP.NET. Active Server Pages are a Windows technology for dynamically generating Web pages via code and scripts and controls. ASP.NET takes that technology much farther, allowing a wide range of client-side and server-side validation, with rich interaction on advanced browsers and graceful degradation of function on less powerful browsers.

  • Web controls. These are custom controls that may be hosted in ASP.NET pages, and that are designed to maintain data or state information and render it as HTML code.

  • WinForms (aka GDI+). The Windows Graphical Device Interface has pro- vided device-independent windowing and graphical user interfaces for more than a decade. WinForms is the latest generation of this technology, allowing faster, safer, and more powerful desktop applications.

  • .NET controls. These are custom controls that may be hosted in WinForms, and that are designed to maintain data or state information and render it using GDI+.

Since console apps are as dead as the dodo (and painful, too), I recommend against this choice. I would recommend a WinForm if you want this UI to run as a stand-alone desktop application; but since some of the user interface will be Web based, an ASP.NET page might make more sense if you want a consistent browser-based UI across the system.

Other swimlanes might represent a number of .NET technologies:

  • Internal classes. A WinForms app can contain any number of classes, and the swimlanes might represent the classes. More interestingly, because ASP.NET is a true OO technology (as opposed to a simple scripting environment), an ASP.NET app can also contain multiple classes. I don’t recommend this approach, however, because you’re working at an external, architectural level at this point. Classes are an internal issue.

  • Class libraries. A class library is a stand-alone component that provides classes for use by other components. Unlike internal classes, a class library is appropriate to discuss during an architectural overview.

  • Interfaces. As discussed previously in this chapter and in Chapter 1 (and again in Chapter 4), an interface is a set of services provided by some component. .NET supports the interface concept as a fundamental part of the environment.

  • Web services. A Web service is a program that resides on some Web server and that may be accessed through XML messages. .NET is one of many platforms that supports Web services. Because these platforms all conform to some standard XML message formats (a protocol known as SOAP), clients written for one may be able to work with another. Thus, Web services provide interoperability between environments (and sometimes a performance penalty, of course, since XML is a text-based format and thus not as compact as binary).

  • .NET Remoting. If the client and server environments are both .NET, you have an alternative to Web services: .NET Remoting, a powerful binary standard for remote components.

  • ADO.NET. Active Data Objects is a Windows technology for COM access to databases (and data sources that behave much like databases). ADO.NET extends that technology into .NET, and adds a lot more power. If the server is primarily a database, an ADO.NET interface will let clients easily access the data.

  • Native code. .NET provides wrapper classes and mechanisms for wrapping native Windows DLLs inside well-behaved .NET components. This can be extremely useful when integrating legacy code into your new designs.

  • COM Interop. .NET provides powerful mechanisms for .NET components to interoperate with COM components, making your .NET designs imme- diately binary compatible with a very large range of existing Windows code.

The best decision will depend on your chosen architecture, which we’ll discuss in Step 4.

Exercise 203: Assign Responsibility to Swimlanes in Your Activity Diagrams:
In this exercise, you’ll take the Activity Diagrams you created in Exercise 202, identify swimlanes for them, and reorganize activities and update items accordingly. You can do this by following in detail the process described in the next section, adjusting your own model at each stage.

{mospagebreak title=Step 3 Process in Detail}

Step 3: Process in Detail

The Activity Diagrams that you created in Step 2 serve as your starting point. In Step 3 of Five-Step UML, you need to work through these diagrams, adding swimlanes to each of them. The best place to start is with the actor that initiates the use case, and then you can look at every activity in turn and think about what part of your system should be responsible for it.

Let’s have a look at this process in more detail.

Pick an Activity Diagram

You need to start somewhere, so pick an Activity Diagram. Go for a simple one first off, particularly if you’re trying to get some practice. You can work on more complicated diagrams later.

Look at the Initial State

Add a swimlane for the actor that requested the corresponding use case. Drag the initial and terminal states into that swimlane. (Here is where you’ll really appreciate a modeling tool or Post-it notes.) Or perhaps you’ll want to preserve the original diagram and re-create it with swimlanes.

Look at the First Activity

Look at the first activity and try to figure out which existing actor or interface should be responsible for that activity. If it’s an activity performed by an actor, the actor is responsible. If it’s an activity performed directly in response to an actor (such as processing user input or responding to a timer or receiving a message), an interface for the corresponding actor is responsible. If it’s a query to a database, a database interface is responsible. If it’s a call to an existing interface, that interface is responsible. And if the activity doesn’t seem to “belong” to any existing actor or interface, add a new interface that is responsible for it, as described in the next part of this exercise.

When adding interfaces, think in terms of high-level groups of services that together form a useful set of services.

For a New Actor or Interface or User Interface, Add a Swimlane

If the actor or interface has not been used in the current Activity Diagram before, add a swimlane for it. If the new element is a heretofore-undiscovered actor, add it to the Actor List. If the new element is a heretofore-undiscovered interface, add it to an Interface List. (You may find it convenient to maintain this Interface List as an evolving Component Diagram. We’ll see more about Component Diagrams later on in this chapter.) Brainstorm about the purpose of the new interface and what sort of other operations it might support.

Drag the Activity into the Swimlane

Now that you have identified the correct swimlane, drag the activity into it. If the swimlane represents an interface, add the activity to the interface (in the Interface List) as a required operation. If the swimlane represents a user interface, add the activity to the user interface (in the User Interface List) as a required operation.

Update All Transitions to Keep the Activity Diagram Intact

If you’re drawing the diagrams by hand, you’ll have to correct the transitions to and from the activity that you moved. Consider adding new activities and using the «invoke» and «interrupt» transitions where appropriate.

Repeat for All Branches, Merges, Activities, Forks, and Joins in the Diagram

Continue revising and adding swimlanes until each element of the diagram has been assigned to a swimlane. Rearrange the swimlanes and activities until you’re comfortable with the assignment of responsibilities. Make sure you keep all interface icons, class icons, and node icons up to date with these changes.

Search for Implicit Requirements and Back-End Activities

Look at your architectural assignments, and see what’s missing. Have implicit requirements been revealed? Have you found back-end activities that are needed? Add the new activities, along with swimlanes for interfaces to support them.

Consider Subactivity States and Additional Diagrams

As in Step 2, consider adding subactivity states and contained diagrams where they simplify the message.

Repeat for Each Activity Diagram

Add swimlanes to each of the remaining Activity Diagrams. Reuse interfaces where appropriate, but try to keep each interface cohesive. Don’t assign an activity to a given interface unless it fits the overall purpose of the interface.

If you’re working through this process as an exercise, then I recommend that you add swimlanes to at least two Activity Diagrams for practice, and more if you wish.

Example

As an example, Figure 2-15 is the Activity Diagram for the Locate Pet use case (shown in Figure 2-9), with an initial swimlane for the actor added.


Figure 2-15.  Activity Diagram for Locate Pet use case (with Swimlanes)

To add further structure to this, we can add activities that reflect the Pet Owner controlling the process, and we can add support interfaces to carry out back-end services. This is shown in Figure 2-16.

There are a few interesting things to note on this diagram:

I rearranged some of the flow, so that if the pet name is wrong, we simply display an error message. It’s up to the pet owner to reenter the name. Nothing in the application forces the pet owner to do so.

Note that the Call for Pet activity uses the Fetch Pet activity of the Care Giver swimlane (corresponding to the Care Giver actor). It does so via an «invoke» transition to the Call for Pet activity of the Care Giver UI, which then instructs the Care Giver to fetch the pet. This diagram doesn’t indicate the mechanism behind this asynchronous UI request. It might be a pager, it might be a pop-up message, it might be electrodes implanted in the care giver’s brain, but you can’t tell from this diagram. That is an implementation issue for the Care Giver UI.


Figure 2-16.  Activity Diagram for Locate Pet use case (interfaces added)

Next, let’s turn the preceding diagram into an architectural diagram by wrapping the business rules in subactivity states, as shown in Figure 2-17.


Figure 2-17.  Activity Diagram for Locate Pet use case (architectural view)


TIP: For more on swimlanes, architecture, and interface design, see Chapter 8.

 

Step 4: Design and Step 5: Repeat will appear next week.

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye