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: SwimlanesSwimlanes 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.
Here, I’ve added four swimlanes:
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:
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:
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.
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”:
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:
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.
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.
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.
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:
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:
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:
blog comments powered by Disqus |
|
|
|
|
|
|
|