Support translation: http://amzn.to/1Z7d5oc
“”The UML is the standard language for specifying, visualizing, constructing, and documenting all the artifacts of a software system.””
The logical place to start walking through some of the UML diagrams is by looking at activity diagrams.
Figure 2: Activity diagram
Activity diagrams show the flow of control. As illustrated in Figure 2, you can see activities represented as rounded rectangles. Activities are typically action states â€” states that transition automatically to the next state after the action is complete. The filled in circle represents the start of the activity diagram â€” where the flow of control starts. Transitions shown as arrows show how you move from activity to activity. Synchronization bars show how activities happen in parallel. I can guard a transition that says “”I want you to go to this activity only if this condition is true,”” and I can show you where it stops. Now if you’re a certain age, you’ll probably look at this activity diagram and think, “”hmm â€¦ that looks like a flow chart.”” And that’s exactly what it is, except I’m not doing it down at the programming level. Typically, I use an activity diagram fairly early on in my analysis and design process to show business workflow. I’ll also use them to show where each of my use cases might be in an activity to illustrate what use case has to happen. I also use activity diagrams to show how things flow between my use cases.
But one of the great things about the UML is its versatility. So while I use activity diagrams at the beginning of the lifecycle, others can use them in a different phase entirely. I’ve seen people use activity diagrams down at the design level where they had a very complicated set of algorithms for a particular class. And many people use them to show the flow between the methods of a class.
the system. Actors are represented as stick figures.
Figure 4: Actors
The example that I worked up for this introduction to UML is a little model of a course registration system. So in this instance, the first thing I would do when starting my analysis process is to ask, “”who is going to interact with this system?””
For the course registration model, I have a registrar, a professor, and a student. I also have an external billing system. This billing system also qualifies as an actor. (See, an actor doesn’t have to be a person â€” it’s anything that interacts with the system but is outside of the system.)
A use case is a sequence of related transactions performed by an actor in the system in a dialog. Or, to put it in English, a use case is a chunk of functionality. And here’s the key: it is not a software module â€” it is something that provides value to the actor.
Use cases are shown as ovals, and the easiest way to find them is to look at each of your actors and ask yourself why do they want to use the system. In my case, my registrar is going to maintain the curriculum, my professor is going to request a roster, my student maintains the schedule, and my billing system receives the billing information. So I create my use cases by looking at it from the customer point of view and asking, “”so, mister system actor, why do you want to use the system? What value does this system provide to you?””
The next step, once you’ve identified how your actors will be interacting with the system, is do document your use cases. Each use case needs to be documented with the flow of events, and this is done from the actor’s point of view. It should detail what the system must provide to the actor when the use case is executed. Typically it will show things like how the use case starts and finishes. What things does that use case have to do? You’ll have the normal flow of events (what I call the “”happy days”” scenario), where everything works. Then you’ll get the abnormal flow of events, the “”rainy day”” scenario. What happens when the system doesn’t work? I’ve found by documenting my flow of events that I always start with the happy days scenario.
Take as an example, walking up to an automated teller machine. You walk up to the ATM and insert your card. It asks for your PIN number. You enter it, and you are asked what you would like to do. You say “”I want some money.”” It asks where the money should be taken from. You tell it to take it from your checking account. It asks how much. You say $100.00. Then magic happens â€¦ it gives you $100.00. Then it asks if you want another transaction. You say no. It gives you your card back, gives you a receipt, and the transaction is over. That’s the happy day scenario.
Second scenario. You go up to the ATM, insert your card, and enter your PIN. The ATM tells you it’s the wrong PIN. You enter your number again. Again you are told that the PIN is incorrect. You In my course registration example, for instance, you can see that there are a lot of “”if X then Y”” workflows. That’s where you want your customer to help you out. Getting agreement early means your customer understands these scenarios and says “”yes, this is what we want.”” Use cases are a great way to ensure that what you’re building is really what the customer wants, because they show the actors, the use cases, and the relationships between them.
Figure 5: Use case diagram
So we have a great diagram that graphically shows me what? The answer is simple â€” it is a great diagram that shows a good overview of the system. It shows what is outside the system (actors) and the functionality that the system must provide (use cases). If there is a legacy system you need to take into consideration, here’s where you deal with it. Forcing me to work with these types of interfaces very early in the project means that I won’t be faced with the prospect of waiting until coding starts to figure out how I’m going to talk to that black box that I can’t change.
One more thing you should know about use cases is the use case realization. This is the “”how”” of the use case. It’s usually a bucket that contains three different types of diagrams: sequence diagrams, collaboration diagrams, and a class diagram that we call a view of participating classes. Use case realizations are basically a way of grouping together a number of artifacts relating to the design of a use case.
Sequence diagrams show object interactions arranged in a time sequence. I can use the flow of events to determine what objects and interactions I will need to accomplish the functionality specified by the flow of events.
Figure 6: Sequence diagram
Figure 6 shows how a student successfully gets added to a course. The student (let’s call him Joe) fills in some information and submits the form. The form then talks to the manager and says “”add Joe to Math 101.”” The manager tells Math 101 that it has to add a student. Math 101 says to Section 1 “”are you open?”” In this case, Section 1 replies that they are open, so Math 101 tells section 1 to add this student. Again, sequence diagrams are great tools in the beginning because they show you and your customer step-by-step what has to happen.
From an analysis point of view, I’ve found over the years that sequence diagrams are very powerful in helping me drive requirements; especially requirements that are hard to find. User interface requirements, for instance, are notorious because you always seem to get requirements that are just not testable. A common UI requirement like this is “”this system shall be user-friendly.”” How many of you have met a friendly computer? One of the benefits of these types of diagrams is that every line coming from an actor that represents a person, tells you that something in your UI has to provide a capability needed by that person. In other words, you can use sequence diagrams to drive out testable user interface requirements.
Sequence diagrams are, therefore, good for showing what’s going on, for driving out requirements, and for working with customers. That usually leads to the question, though, of how many do you need to create? My answer is, “”until you do enough.”” You’re going to find out when you do sequence diagrams that you reach a point where you’re not finding any new objects, not finding any new messages, and that you’re typing the same thing over and over. In the example of Joe joining Math 101, we learn that the process would be the same if Joe wanted to join History 101. So, rule of thumb, do a sequence diagram for every basic flow of every use case. Do a sequence diagram for high-level, risky scenarios, and that should be enough. That’s how many sequence diagrams I do.
to remember here, is that a collaboration diagram is just a different view of a scenario and you can go back and forth between sequence diagrams and collaboration diagrams to get the view that best illustrates your point.
Occasionally, you might hear the phrase “”interaction diagrams.”” Sometimes people will collectively refer to a collaboration diagram and a sequence diagram as an interaction diagram.
A class is a collection of objects with common structure, common behavior, common relationships, and common semantics. You find them by examining the objects in sequence and collaboration diagrams, and they are represented in the UML as a rectangle with three compartments.
Figure 8: Classes
The first compartment shows the class name, the second shows its structure (attributes), and the third shows its behavior (operations). These compartments can be suppressed, however, so that you can see just the name, just the name and the attributes, or all three. One thing you should also know is that it’s important, when naming classes, to use the vocabulary of the domain and pick a standard. For this instance, my classes are all singular nouns that begin with a capital letter. You may choose to do it differently, and that doesn’t matter. What does matter is that before your project you pick a standard and stick with it so that everything is consistent across the project.
Class Diagrams show you the static nature of your system. These diagrams show the existence of classes and their relationships in the logical view of a system. You will have many class diagrams in a model.
The UML modeling elements found in class diagrams include:
Classes and their structure and behavior.
Association, aggregation, dependency, and inheritance relationships.
Multiplicity and navigation indicators
Take a look at Figure 9. This diagram shows operations (behavior): what an object in that class can do. I find my operations by looking at my interactions diagrams.
Figure 9: Operations
Here I’m saying that I need to be able to ask the registration manager to add a student to Math
101. That’s going to translate into an operation called “”addCourse.””
The structure of a class is represented by its attributes. So how do I find my attributes? By talking to domain experts. By looking at my requirements. In my example, I learn that each course offering has a number, a location, and a time. This translates out to three attributes.
classes. (Represented in the UML as a line connecting the related classes with a diamond next to the class representing the whole.)
â€¢ Dependency â€” a weaker form showing the relationship between a client and a supplier where the client does not have semantic knowledge of the supplier. A dependency says “”I need your services, but I don’t know that you exist.”” (Represented in the UML as a dashed line pointing from the client to the supplier.)
To find relationships, once again, I go back to my sequence diagram. If two objects need to “”talk””, there must be a means to do so (i.e., a relationship between their classes).
I typically start out and make everything an association. As I’m doing more analysis, I might find I have an aggregation because I’m going to have to take care of a parent-child relationship. When I get into the design phase, I find out that I might not need an association because somebody else is going to pass that object into one of my methods â€” so I make it a dependency.
Figure 11: Relationships
In Figure 11 you see these relationships. As association says the Professor can talk to the Course Offering, and the Course Offering can talk to the Professor. Messages can be initiated and data can flow from any direction. Aggregation is shown by having the diamond toward the whole â€” in this case a Course is made up of Course Offerings. The reason for this aggregation would be to tell my developers that if they get rid of this Course, they’ll probably have to do something special with the Course Offerings. Dependencies are shown as a dashed line. It’s saying that the registration manager depends upon the Schedule Algorithm to do something. The Schedule Algorithm is either a parameter to one of the methods or is declared locally by one of the Methods of the Registration Manager.
Multiplicity and Navigation
Multiplicity defines how many objects participate in a relationship. It is the number of instances of one class related to one instance of the other class. For each association and aggregation, there are two multiplicity decisions to make: one for each end of the relationship. Multiplicity is represented as a number and a * is used to represent a multiplicity of many.
Figure 12: Multiplicity and navigation
One Professor Object is related to zero-to-four Course Offering Objects. One Course Offering Object is related to exactly one Professor Object. I use this to look at and ensure that this handles my requirements. Can I be a Course Offering and be team-taught by a bunch of professors? No, because this says I can only have one professor. Can I be a professor and be on sabbatical? Yes, because this says I have a zero as possible course load. I use multiplicity quite often to help me start capturing and implementing my business rules. If you have, for example, a business rule that says you must have at least 3 students and no more than 10 for a course to be offered in a semester, these multiplicity numbers tell me I’ve incorporated that business rule into this plan.
Navigation is shown by an arrow, and although associations and aggregations are bi-directional by default, it is often desirable to restrict navigation to one direction. When navigation is restricted, an arrowhead is added to indicate the navigational direction. One of the things I do during the analysis and design phases is look at what I want to be uni-directional. By putting the arrow into this diagram, I say that the Registration Manager can send a message to the Course, because it knows the Course exists. But the Course has no idea that the Registration Manager exists, so the Course cannot initiate a message. Now data can flow between them; for instance the Registration Manager can ask the Course if it’s open and the Course can say that it is. But only the Registration Manager can start that conversation.
Obviously the goal here is to get as many arrows as you can by the time you’ve finished designing, because it’s a much easier system to maintain Inheritance is shown with a triangle. This shows that the Professor is a Registration User, as is the Student. Now, a word of warning. Inheritance is useful, however, the goal is not to use as much inheritance as your system will allow. I’ve seen some really brutal systems where they had inheritance 17-levels deep. If they changed one thing, it became a disaster. So the rule of thumb is to use inheritance only when you truly do have an inheritance situation.
State Transition Diagrams
A state transition diagram shows the life history of a given class. It shows the events that cause a transition from one state to another, and the actions that result from a state change.
Figure 14: State transition diagram
I use state transition diagrams for object classes that typically have a lot of dynamic behavior. The button is on â€¦ the button is off; I’m not going to do a state chart for it. But object classes that have a lot of dynamic behavior, I’m probably going to have to look into the states of the objects.
I start by showing a state, which is a rounded triangle. I can have start states, and I can have stop states, which are shown as bulls eyes. I can also have transitions between states, or guard transitions (things that happen when only when a condition is true), or things that happen when I’m inside the state. I look at this diagram and see the state transition diagram for a course offering. It starts in the initialization state, and I stay in that state until I get an “”add student”” message. When I get that message, I set my count of student to zero and I transition to the Open state. You’ll see in Figure 14 that I have an entry, and the reason why it’s there is that I have two ways of getting into that state. It says that no matter how you come into the state, I want you to register the student. When I exit that state, the count changes to keep track of the number of students in the course. I can keep adding students until I get to 10, and then I go to the Close state. Once the course is finalized, I transition to the stop state. No matter where I am then, if I get the Cancel Event transition, I notify my students and then transition to the stop state.
For object classes that have a lot of dynamic behavior, it’s well worth it to do a state diagram to get a handle on everything that has to happen. Ask yourself what happens when I get a message? What do I do when I get the message? What messages to I have to send? A lot of those messages become operations of the object class, as in this example where add a student is an operation. A lot of these actions, like setting the count, incrementing the count, checking the count, these all become private operations of that particular object class and a state diagram is where I see that.
How do you know if you have a dynamic object class? Once again, go back to the sequence diagrams. If you have an object class that’s on a lot of sequence diagrams and it’s getting and sending a lot of messages, that’s a good indication it’s a fairly dynamic object class and it should probably have a state chart for it. Also for aggregations, where you have the whole of its parts, I do a state chart for every aggregate whole. I do this mostly because that aggregate whole is often responsible for managing the messaging, which makes it dynamic.
Of course no system can be built without taking into account the physical world. That’s where component diagrams come in. They are used to illustrate the organizations and dependencies among software components, including source code components, run time components, or an executable component. Components are shows as a large rectangle with two smaller rectangles on the side, as seen in Figure 15.
Figure 15: Components
Those round things represent interfaces (often called lollipop notation). In this case, they show that the Register.exe is dependent upon interfaces to both the Course.dll and the People.dll. That means if these interfaces change, it will impact the Register.exe. I know that there’s this rule when you’re building interfaces that says “”thou shall not change the interface.”” But does anybody actually work where that rule is enforced? This diagram tells us what interfaces are used by what executables are running on my processors.
Figure 16: Deployment diagram
The last thing I want to stress about the UML is that it can be extended. When they built the UML, they very wisely realized that there was no way they could create a notation that could please all of the people all of the time. So they gave us the concept of a stereotype. A stereotype says I can take a basic modeling element and give it more meaning. Stereotypes may be used to classify and extend associations, inheritance relationships, classes, and components.
Figure 17: Web stereotype example
Figure 17 shows the diagram of our Web stereotypes. A Web page typically has stuff that runs on the server and stuff that runs on the client. If you’re building Web-based applications, what’s running on the client and the server is of vital importance. So we have a whole set of stereotypes that show that. The little wheels represent things that run on the server. So just by looking at this one diagram I can see what runs on the server, what runs on the client, and what business objects they have to deal with.