Did that last step bother you? It bothers me: some of the swimlanes correspond to interfaces, but others correspond to actual components. Now this is legal UML. (In fact, it’s irrelevant UML: UML doesn’t require any mapping from interfaces or components to swimlanes, though the mapping is allowed. We use the mapping here as a useful convention of the Five-Step UML process.) But it’s inconsistent UML. That bugs me. I had a nice, linear process: look at a swimlane; make it into an interface; assign it to a component; look at a component and its swimlanes; draw the dependencies. Now there’s a bump in my process. In fact, there are two bumps: we also have swimlanes that correspond to users of the system, and those don’t show up on the Component Diagram at all. Even worse, those end users are represented in the model as actors; and so are other computer systems with which our system must interact. Yet we interact with those systems via interfaces, which do appear on the Component Diagrams. So we have two kinds of actors and two kinds of swimlanes that are similar in nature (within our model, anyway); but one is represented on the Component Diagram, and one isn’t. Traditional architecture diagrams don’t actually represent the end user; but if architecture is about “ . . .the selection of structural elements and the interfaces through which they are connected, the large-scale organization of structural elements and the topology of their connection, [and] their behavior as specified in the collaborations among their elements . . .”,9 then I believe it is a mistake not to include the end user in relevant architectural diagrams. Users are “connected” to the system through user interfaces; the topology of elements is shaped in part by the users with which it must be “connected”; and users collaborate with the system to do work (witness the fact that actors can appear as collaborators in Sequence Diagrams). We can smooth out both of these bumps by adopting a new stereotype, «user interface», which may be applied to interfaces. The attributes of a «user interface» element represent the data fields displayed by the UI; and the operations of a «user interface» element represent the actions a user may take through the UI. Besides defining this stereotype, I find it useful to define a custom icon that looks somewhat like a computer monitor. Its square shape makes it easy to distinguish from regular interfaces.
Then we can add «user interface» elements to the Component Diagram the same way we added regular interfaces: look at a swimlane that represents a user interface, and add the corresponding «user interface» element. Then document the «user interface» element in a Class Diagram to depict its data fields and actions. So, for our example, the user interfaces we have defined so far could be modeled in a Class Diagram as shown in Figure 2-26.
9. James Rumbaugh, Ivar Jacobson, and Grady Booch. The Unified Modeling Language Reference Manual (Addison-Wesley, 1999), p. 151 And then we can select or define a user interface component to realize the «user interface» element. Following this procedure (and ignoring that whole vital stats controversy—what was I thinking when I put that in the architecture?), the diagram in Figure 2-23 would now look like the one in Figure 2-27.
Note how we assign one component for each user interface. This is a common practice for modeling ASPX pages: each page is a component in its own right. In this sense, we can think of the user interface as the HTML delivered to the user’s browser, and the component as the code-behind component that creates the HTML and processes the response. Although this approach can be useful, it can also be cumbersome, as you’ll see in Chapter 9. Note also how, by adding «user interface» elements and corresponding components, we pick up something we had missed in our architecture earlier: the Paging System to notify the Care Giver when the pet needs to be retrieved. This is certainly an improvement in our architecture; but it also reveals another problem. In Figure 2-17, we have one user interface swimlane (Check Out UI) calling another (Care Giver UI). Now this is legal, because a form can certainly launch another form; but it’s clearly not what we meant: we wanted an interprocess communication that would cause the Care Giver UI to notify the Care Giver. Interprocess communication implies a new interface, one we didn’t capture correctly in Figure 2-17. We’ll call it Care Giver Notify, and add the corresponding swimlane to the diagram in Figure 2-17, producing the one shown in Figure 2-28.
Note the use here of a new stereotype, «display», applied to a transition to a user interface to indicate that it must display information for the user’s response. From this diagram, we can add the Care Giver Notify interface to the diagram in Figure 2-27, producing the one in Figure 2-29.
Next we can add dependencies the same way we did before. Recall that in order to add dependencies, we examine each swimlane, and look at the swimlanes that have transitions into it, converting those into dependencies. By following this procedure and rearranging for legibility, we get the diagram in Figure 2-30.
Now that we’ve gone this far, we might as well go all the way: adding the actors corresponding to swimlanes, and adding dependencies from the actors to the user interfaces they use. This will give us a complete picture of the roles that users play within the architecture, as shown in Figure 2-31.
If you would rather stick with formally correct UML notation, you could define a new stereotype for components: «user». You could then add a new component with that stereotype wherever you want to show a user interacting with a user interface. But even though it’s not standard UML, I find it easier and clearer to just put the actors on the Component Diagrams, as shown above. And again, if it helps you to communicate, it’s useful UML, even if it’s not perfect. So What About Those Names? Here in Step 4, we’re stepping out of analysis and into design (architectural design, to be precise). That means the programmers in the crowd are starting to think about implementation (because we programmers have a nasty habit of running ahead of where we’re supposed to be). And that means that some of you reading this right now are saying, “Hey, those names aren’t legal identifiers in my implementation language. What’s up with that?” And you’re right, of course: Kernel Management Engine, Owner Info, and Get or Add Owner aren’t legal identifiers in any programming language I know. And if you start talking corporate naming standards and coding conventions, the situation only gets worse. So what is up with that? Well, in my practice, I usually try to share my architecture with my stakeholders as it evolves, so that they can give me an outside perspective. (OK, I really only share selected, simplified views. I don’t want to bury them in technical details.) So I prefer human-readable names. andIfYouThinkThisIsHumanReadable, youHaveBeenProgrammingTooLong, and youNeedToGetOutIntoTheRealWorld. So how do I deal with this disconnection between readable names in my model and legal identifiers in my code? I have three suggestions:
TIP: To learn more about Component Diagrams and architecture, see Chapter 8.
blog comments powered by Disqus |
|
|
|
|
|
|
|