COMP433 · Ch. 4 · UML & system modelling
COMP433 · Software Engineering · Chapter 4

UML and system modelling: seven views of one system.

System modelling is the engineering practice of producing selective abstractions of a system, each one emphasising a single concern (interaction, structure, behaviour, deployment) and ignoring the rest. The Unified Modelling Language (UML, ISO/IEC 19505 since 2012; current version 2.5.1, 2017) is the OMG-standardised notation in which these models are drawn. This companion covers the discipline's origin in the work of Booch, Rumbaugh, and Jacobson (the Three Amigos, 1994 to 1997), the four families into which models sort, accurate notation for the seven diagrams covered in depth, and a worked example that follows one user requirement from elicitation to first-cut design.

courseCOMP433
chapter4 of the syllabus
instructorHisham Ihshaish
textbookSommerville (10th ed.)
Recorded session by Prof Adel Taweel

Chapter 4 lecture: UML and system modelling

Recorded session covering much of Chapter 4. Read this companion alongside the recording for notation references, hover-enabled diagrams, and the worked example tracing one user requirement through to a first-cut class fragment.

Lecture decks by Prof Adel Taweel

Chapter 4 slides: UML diagrams

The Chapter 4 lecture deck, in its parts. This companion follows these decks; download them for the original slides and the in-class exercises.

Contents

Short on time?

Focus on three sections: Use case diagrams (Section 5), Activity diagrams (Section 7), and the back-to-back case study (Section 7b), which draws both diagrams from one set of requirements. Sections 1 to 4 are background and 8 to 14 are wider breadth.

1.Motivation

Why we model: selective abstraction as engineering tool.

Software engineering is the discipline that builds large, useful programs without their complexity becoming the dominant cost. Modelling is one of the levers that keeps complexity under control: a model shows part of the system clearly precisely because it hides everything else. Different stakeholders need to see different parts, which is why there is no single diagram type that captures a system, and why this companion treats seven of them.

The idea of a "model" in engineering predates software. In mechanical, civil, and electrical engineering, drawings replace prose because they are denser, more checkable, and (when standardised) less ambiguous. The same case applies to software, with one extra wrinkle: the artefact we are modelling does not yet exist, so the model has to do double duty as both description (of what we intend to build) and specification (of what counts as having built it correctly). Sommerville (Software Engineering, 10th ed., 2015, ch.5) captures this in a one-sentence definition that is worth taking apart:

"A model is an abstract view of a system that ignores some system details. Complementary system models can be developed to show the system's context, interactions, structure, and behaviour."

Sommerville (2015), Software Engineering, 10th ed., chapter 5, opening definition.

Two words in that sentence carry the weight: ignores and complementary. A model ignores by design; if it captured every detail, it would be the system itself, and would offer no leverage. And no single model is enough: a use case diagram says nothing about how data is structured, a class diagram says nothing about how messages flow over time, a sequence diagram says nothing about how the system is deployed across machines. Complementary models compose into a full picture because each ignores something different, and the engineer's job is to know which complement to add next.

The shorter, practitioner-facing summary is: a model is the language of the designer; a description of the system-to-be-built (or as-built) from a particular perspective; a tool for communicating with stakeholders; and a means of reasoning about some characteristic of the system without holding the whole of it in your head. UML, the Unified Modelling Language, is the standardised vocabulary in which those models are now drawn. The rest of this chapter develops where UML came from, where it is used in practice, and how to choose which model to draw, before turning to how to draw each of the seven course diagrams correctly. A worked example near the end ties them together from elicitation to first-cut design, and a closing section lists the marking pitfalls.

Two questions a model must answer

Before you draw a model, you should know which two questions it answers, because if it answers neither, it is not earning its place on the page:

Every diagram below is paired with a short "where it earns its place" panel that names the reader and the decision it supports. Those two anchors, the audience and the decision, are what separate a useful diagram from a decorative one.

Three modelling moves

Underneath the fourteen UML diagram types are just three modelling moves you make again and again. Recognising which move you are making is the easiest way to pick the right diagram:

If you find yourself drawing a diagram without doing one of these three moves, the diagram is probably not adding value; you are decorating.

A model earns its place by what it makes discussable. A use case diagram makes the system's interactions with its users discussable in a single page; a class diagram makes its static structure discussable; a sequence diagram makes one specific interaction discussable. None of them captures the system, and that is exactly the point.

2.History

The Three Amigos and the method wars.

UML did not arrive whole. It was the result of a deliberate, three-year unification at Rational Software (1994 to 1997) of three competing object-oriented modelling notations, led by the engineers who had created them. Understanding that backstory matters, because every UML diagram type still bears the fingerprint of which of the three contributed it.

Before UML: the method wars

The 1980s and early 1990s were the boom years of object-oriented analysis and design. Smalltalk had been released in 1980; C++ in 1985; Java arrived in 1995. As industry adopted these languages, the demand for diagrammatic notations to plan large object-oriented systems exploded. By the early 1990s the field had no fewer than fifty published methods, each with its own conventions for classes, associations, inheritance, and behaviour. Fowler later called the period the "method wars" (UML Distilled, 2003, ch.1): teams that adopted one method could not exchange diagrams with teams that adopted another, and reading the OO literature meant learning a different graphical vocabulary every few months.

Three of the methods dominated by 1994. Each was associated with one prominent author, each came out of a different industrial setting, and each was strongest in a different part of the lifecycle:

AuthorMethodStrengthWhat it contributed to UML
Grady Booch
(Rational Software)
Booch method (1986, refined 1991 and 1994 in Object-Oriented Design with Applications).Architectural and design-level modelling. Introduced the distinctive "cloud" class symbol and a granular notation for module dependencies and visibility.Class diagrams (the three-compartment box), package diagrams, component diagrams, and most of UML's structural-modelling vocabulary.
James Rumbaugh
(General Electric R&D)
Object Modeling Technique (OMT) (Rumbaugh, Blaha, Premerlani, Eddy, and Lorensen, 1991).Analysis-level modelling for large data-rich systems. Strong on associations, multiplicities, and the data model.The now-universal class-diagram notation with associations and multiplicities, plus the state-machine notation derived from Harel statecharts.
Ivar Jacobson
(Ericsson, then Objectory)
Object-Oriented Software Engineering (OOSE) (1992), out of his earlier work on Ericsson's AXE telephone switches.Requirements engineering and process. Originated the concept of the use case.Use case diagrams, the actor / system-boundary notation, and the include / extend stereotypes covered in section 5 of this companion.

The three were complementary in scope (analysis, design, requirements) and convergent in spirit (all object-oriented, all diagrammatic), but stubbornly incompatible in notation. A class drawn in OMT looked nothing like a class drawn in Booch, and Jacobson's use case bubbles had no equivalent in either. Teams that mixed methods spent disproportionate effort translating between them.

The unification: 1994 to 1997

The first move came in October 1994: Rumbaugh left General Electric to join Booch at Rational Software, with the explicit goal of merging OMT and the Booch method. They circulated a draft "Unified Method" version 0.8 in October 1995. Jacobson sold Objectory to Rational the same month and joined the team; from that point the three were collaborating in one company, on one notation. Industry shorthand quickly named them the Three Amigos, after the 1986 film.

The unification was not a vote between three favourites; it was a re-engineering of the combined notation around what each method did best. Rumbaugh's class-and-association notation became UML's structural backbone; Jacobson's use cases were lifted in essentially unchanged; Booch's emphasis on design-level diagrams supplied component and deployment views. The result was published as UML 0.9 in June 1996, renamed Unified Modelling Language rather than Unified Method (a deliberate distinction: a language is a notation only, not a prescribed process).

In November 1997, the Object Management Group (OMG) adopted UML 1.1 as a standard. The OMG is an industry consortium founded in 1989 to standardise object-oriented and distributed-system technologies (it also maintains CORBA and SysML). UML's transfer to OMG was the moment it stopped being a Rational product and became a public standard. The notation was frozen at UML 1.1, substantially revised at UML 2.0 (2005, which added the sequence-diagram interaction fragments and refined activity diagrams along business-process lines), and has been stable since UML 2.5.1 (2017), the current version. The point of standardising was readability: after UML, a diagram drawn in one company is readable in another, in a research lab, and in a textbook.

UML is a language, not a method

A common confusion is to expect UML to tell you when to draw each diagram. It does not. UML is a notation only: it standardises the shape of an ellipse for a use case, the rules for an include arrow, the compartments of a class box. The decisions about which diagrams to draw, in what order, and how much detail to put on them belong to the process, which is a separate concern. The most-cited process built around UML is the Rational Unified Process (RUP, Kruchten, 2003), but agile teams routinely use a small subset of UML inside Scrum or XP without adopting RUP at all. The separation carries through here: chapter 3 covers the process by which requirements are produced; this chapter covers the language in which the resulting models are drawn.

3.Current use

Where UML lives now.

UML's status today is uneven across the industry. Knowing where it is heavily used and where it is light-touch is part of using it correctly.

Heavily used. Regulated domains (medical devices, automotive safety, avionics, rail), where traceability from requirements to design is a certification requirement; Model-Based Systems Engineering (MBSE), where SysML (a UML profile) is the primary modelling notation; teaching, where UML's diagrammatic vocabulary is still the standard way to introduce object-oriented design; and large enterprise architecture work, where component and deployment diagrams remain the standard medium for documenting system structure.

Lighter use. Agile teams often use only a subset (use cases or activity diagrams for requirements; class diagrams sketched on whiteboards) and rarely produce the full UML model that the textbook describes. The reasons are pragmatic, not ideological: keeping a heavyweight model in sync with rapidly changing code is expensive, and teams have learned to invest in the diagrams that pay back in conversation rather than those that pay back in documentation.

Areas of growth. The rise of safety- and security-critical AI systems has brought renewed interest in MBSE and formal modelling, including UML-derived notations. The diagrammatic vocabulary has also re-emerged in domain-specific contexts (database modelling tools, infrastructure-as-code visualisers, sequence diagrams generated automatically from distributed traces).

The practical takeaway is that the seven diagrams treated in depth here are all in current use somewhere, and being fluent in them is portable knowledge. The diagrams treated more briefly (object, communication, timing, interaction overview) are still in the standard but are encountered much less often in industry.

4.The map of UML

The map of UML: four families, fourteen diagrams, and where each fits.

Three views of the same territory before the diagrams themselves: the four families of models (what each makes discussable), the fourteen UML 2.5 diagram types, and the journey that places each diagram at its point in the lifecycle.

The four families of models

Sommerville (2015, ch.5) groups system models into four families by what they make discussable. The families are not mutually exclusive (one diagram can belong to two), but knowing the family helps decide what kind of question the diagram is being drawn to answer, and which UML diagram types are the natural fit. Hover any card below for a worked example and a sharper definition.

C

Context models

Where the system sits and what it talks to. Show the system as a single opaque box with its external environment (users, other systems, devices, regulatory interfaces). Answer the scoping question: what is in, what is out, what does it touch?

I

Interaction models

Who talks to whom, in what order, with what messages. Show the dynamic exchange between a defined set of participants (objects, components, actors). Answer the question: given that the parts exist, how do they cooperate?

S

Structural models

Parts and their static relationships. Show the organisation of the system without time. Nothing moves; the diagram captures what exists, not what happens. Answer the question: what is the system made of, and how are the parts connected?

B

Behavioural models

What the system does over time, in response to internal or external stimuli. Dynamic view; states change. Answer the question: given an event, what does the system do next, and could it get stuck somewhere?

Hover any family card above for a concrete example and the decisions that family supports.

The families are not partitions. A use case diagram is partly context and partly interaction; an activity diagram can be either interaction or behavioural depending on the level it is drawn at; a component diagram is structural but its interface contracts already imply interaction. The classification is a thinking aid, not a rigid taxonomy: when a team realises it has drawn three interaction diagrams and no structural one, it has a signal that an important class diagram is still missing.

From elicitation to deployment: where each model fits

The diagrams in this chapter do not exist in isolation. Each one sits at a particular point in the software lifecycle, takes its input from the artefact that precedes it, and produces an output that the next artefact builds on. This part of the map is what the rest of the companion fills in.

A common misconception is that UML diagrams are alternatives ("should I draw a use case or a class diagram?"). The right framing is sequential: each diagram answers a question the previous one raised, at the right level of abstraction for the stage you are in. Knowing which question is on the table is what tells you which diagram to draw next.

Figure 1
The modelling journey: from stakeholder needs to deployable system
Requirements "What must it do?" Analysis & Design "How will it work?" Architecture "Where will it run?" 1. Elicitation interviews, scenarios, prototypes 2. Requirements doc UR / SR, NFRs, domain 3. Effort estimation cost, schedule, quoted price decision gate go/no-go 4. Use case diagram actors, system boundary 5. Activity diagram workflow, swimlanes 6. Class diagram classes, associations 7. Sequence diagram message order, fragments 8. State machine states, transitions, events 9. Component diagram modules, interfaces 10. Deployment diagram nodes, protocols, artefacts classes refine into sequence interactions classes carry the activities iterate: new requirements re-enter at step 1 Legend Requirements artefact (Ch.3) Decision gate Analysis & design diagram (Ch.4) Architectural diagram (Ch.4)
Hover any box for a one-line description of what it is and why it sits where it does. Solid blue arrows show the main forward flow; dashed grey arrows show common refinement loops within design; the long dashed rust arrow shows the iteration that every project has, because deployed software exposes new requirements, which re-enter the pipeline at step 1.
Hover or tap a step in the journey above to see what it is, what feeds it, and what it produces.

Reading the pipeline

Three observations worth pausing on:

  1. Cost estimation is a decision gate, not a deliverable. Steps 1 and 2 produce the requirements; step 3 prices them. The estimate is what the customer needs to authorise the design work (steps 4-10). Doing the estimate too early, before requirements are stable, produces a number nobody can defend. Doing it too late, after design has started, means the team is committed to a price that may not match the work.
  2. The arrows go forward but the work goes back and forward. A class diagram drawn at step 6 usually exposes a missing requirement at step 2, which is added and propagates back through the use cases (step 4). The pipeline is a thinking aid, not a waterfall.
  3. Not every step is mandatory. A small project may skip the activity diagram entirely; a project with no domain objects with lifecycles may skip the state machine. The skip rule is the same as the model rule: if it does not change anyone's decision, do not draw it.

Cost estimation in context

Cost estimation is treated in depth in the Ch.3 companion, which includes an interactive calculator. The view from this chapter is about when and why, not how. The implications:

A worked thread through the journey

To make the pipeline concrete, follow one user requirement through it. The example is the Library System used as the running example in the rest of this companion:

StepWhat it produces for "members can borrow books"
1. ElicitationInterview with the head librarian surfaces the rule "no more than six books on loan at once" and the existence of three loan periods (ShortLoan, MediumLoan, LongLoan).
2. Requirements docUR3: "A library member shall be able to borrow up to six copies of books at one time." SR3.1, SR3.2: derived system requirements with the loan periods and the maximum-loan check.
3. Effort estimationUR3 is estimated at 2 developers × 1.5 person-weeks = 3 person-weeks. Sums into the project total; the customer signs the contract on the price that includes this number.
4. Use case"Borrow copy of a book", with <<include>> "Compute return date" and <<extend>> "Refuse loan [too many books]". Use case description fully written out.
5. ActivitySwimlane diagram showing BookBorrower, Librarian, and System; covers the success path, the "too many books" branch, and the damaged-barcode error.

One user requirement, and already five linked analysis artefacts. Most of the value is not in any single one; it is in the traceability from UR3 onward, which lets the team change the design and know which other artefacts to update. These five are the analysis views this chapter teaches first; section 12 carries the same thread on into the design diagrams (class, sequence, state, component, deployment).

UML 2.5: the fourteen diagram types

The UML 2.5 specification defines fourteen diagram types, split into structural (seven) and behavioural (seven). Nine of these are conventionally treated as the “standard” set encountered on real projects, and seven are covered in depth in the sections that follow. The map below lists all fourteen for completeness; the italicised types are part of the standard but encountered less often in practice.

Figure 2
The UML 2.5 diagram taxonomy. Hover any diagram name for a one-line definition and a section pointer.
UML 2.5 14 diagram types Structural (static) 7 types Behavioural (dynamic) 7 types COVERED IN DEPTH (sections 8, 11) Class classes, attributes, operations, associations Object instances of classes at a moment Component components, provided/required interfaces Deployment runtime nodes and the artefacts on them LESS COMMON IN PRACTICE Package groupings of model elements Composite structure internal structure of a classifier (+ Profile diagram, for extensions) COVERED IN DEPTH (sections 5-10) Use case actors and what they do with the system Activity workflows, decisions, parallelism Sequence interactions over time State machine states and transitions of an object LESS COMMON IN PRACTICE Communication interaction with structure emphasis Timing state changes against time (+ Interaction overview)
Rust labels above the divider mark the seven diagrams covered in depth in the sections that follow. Italic muted labels below the divider are part of the UML standard but encountered less often in practice; knowing they exist is enough at this stage. Hover any name for a fuller definition.
Hover any diagram name in the taxonomy for a one-line definition and a pointer to where it is covered.

The seven types covered in depth below are: use case, activity, class, sequence, state machine, component, and deployment. Together they cover the full life cycle of a typical project: requirements (use case, activity), analysis and design (class, sequence, state machine), and architecture (component, deployment).

5.Use case diagrams

Use case diagrams: actors, tasks, system boundary.

A use case diagram is a one-page picture of who interacts with the system and the named tasks they perform. It is the first UML diagram drawn on most projects: it converts the list of User Requirements into something that fits on one A4 page, makes scope confirmable with the customer, and produces the index of tasks that downstream diagrams (activity, sequence, class) refine.

Where it fits

Requirements analysis. In Adel's lifecycle map, elicitation (interviews, scenarios) feeds the use case diagram; it is the first model drawn, and its tasks become the index that the use case descriptions specify and the activity, sequence and class diagrams later refine.

 In one line
WhatA one-page picture of the actors (the users and external systems) and the named tasks (use cases) they perform, enclosed by the system boundary.
HowFind the actors (the roles/nouns that interact), find the use cases (the tasks/verbs the system provides), join each actor to the use cases it takes part in, then add «include», «extend» and generalisation only where they earn their place. Keep it to one page.
WhenFirst, during requirements analysis, to agree the system's scope with the customer and to produce the task list the rest of the modelling refines. Not for internal logic, data structure, or message order.
In this section

The diagram: what it is and when to draw it; actors and how to find them (users, external systems, time); use cases and how to find them (noun-verb analysis); the building blocks and the system boundary. Refining and detailing: <<include>>, <<extend>>, generalisation and extension points; composite (multi-level) use cases; the use case description; and scenarios (normal, alternative, error). The goal: read a narrative and draw a correct, fully-refined diagram, then write the contract behind it.

What a use case diagram is for, precisely

The diagram serves three decisions, and only three:

Beyond those three decisions, the use case model earns its keep across the whole project. A good use case set does five further things: it specifies the context of the system (its boundary and the actors around it); it lets the team plan iterations of development (each use case is a unit of work to schedule); it validates the architecture (every architecturally significant use case must be realisable on the proposed design); it drives implementation (each use case becomes a thread of construction); and it generates test cases (each scenario through a use case is a system-test script). Use cases are built early in development, by analysts and domain experts during requirements analysis, and stay useful long after.

It does not show: the order of work inside a use case (use an activity diagram), the messages between objects realising a use case (use a sequence diagram), what data the system holds (use a class diagram), or where the system runs (use a deployment diagram). A use case ellipse is, deliberately, an opaque label; the substance lives in the textual description.

When the diagram is drawn

In the project pipeline (section 4, figure 1), the use case diagram is the bridge between requirements and design. It is drawn for the Phase 2 deliverable: each User Requirement that names a clear actor and a clear goal becomes one use case, and the diagram makes the relationships between them (sub-tasks, conditional alternatives) visible alongside the textual UR / SR list. It is then revised at the start of Phase 3 as design begins, because the design pass surfaces additional sub-tasks (which become <<include>> use cases) and alternative paths (which become <<extend>> use cases).

Building blocks

A use case diagram has three building blocks: actors, use cases, and the system boundary. Actors are drawn as stick figures (or sometimes labelled boxes for non-human actors) outside the boundary; use cases are ellipses with a verb-phrase label inside the boundary; the system boundary is a rectangle that contains the use cases and explicitly excludes the actors. Associations are simple solid lines between an actor and a use case they participate in (no arrow head, because participation is undirected). Refinement relationships between use cases are drawn as dashed arrows with one of three stereotypes: <<include>>, <<extend>>, or generalisation (inheritance).

Building blocks, drawn correctly

Figure 3
A complete use case diagram: Library system. Hover any element for an explanation.
Library System Borrow copy of a book Refuse loan Return copy of a book Compute return date Renew loan of a book Browse / search books BookBorrower (library member) Librarian (staff) Browser (non-member) <<extend>> [too many books] <<include>> <<include>>
Six use cases inside the Library System boundary. Solid light-blue lines are actor / use case associations. The dark dashed arrows are <<include>> relationships; they point from the base case to the included case (Borrow and Renew both include Compute return date). The warm-rust dashed arrow at the top is the <<extend>> relationship; it points from the extending case to the base (Refuse loan extends Borrow when the guard [too many books] holds). The two stereotypes are kept on different horizontal bands and given different ink colours so it is unambiguous which label belongs to which line. Mnemonic: an include's base cannot run without its include; an extend's base usually runs without its extension.
Hover any actor, use case, line, or arrow to see what it represents and why it sits where it does.
Context

Where use case diagrams earn their place

Problem they solve

Capturing what the system has to do for whom, before any commitment to how. They make the system's external surface explicit and let stakeholders confirm or contest scope on one page.

Domains where they dominate
  • Regulated software (medical devices, avionics under DO-178C, automotive under ISO 26262) where traceability from requirement to test is a certification requirement.
  • Healthcare interoperability (HL7 use cases, IHE profiles).
  • Enterprise systems built on the Unified Process (RUP) and its variants.
  • Public-sector procurement, where a use case list is often part of the tender document.
Problems they do not solve

Internal algorithms, data structures, performance behaviour, security mechanisms, transaction boundaries. Use cases are a contract sketch, not a design.

Tooling in current use

Enterprise Architect (Sparx), Visual Paradigm, Lucidchart, draw.io, PlantUML (text-driven, popular in GitHub-based teams), and increasingly Mermaid for inline-in-Markdown documentation.

Documented industrial use. Jacobson's Object-Oriented Software Engineering (1992) reports the original Ericsson telecoms work that produced use cases. The Rational Unified Process built an entire methodology around them in the late 1990s. HL7 v3 (healthcare data exchange) and the IHE Technical Frameworks (cross-vendor medical interoperability) publish use case diagrams as part of standards documents.
Project link. For your Phase 3 deliverable, the use case diagram is the bridge from the requirements document you produced in Phase 2 to the system models that follow. Every UR with a clear actor and goal becomes a use case here; the include and extend relationships capture the structure your SRs encoded textually.

Actors: primary and secondary

An actor is a role someone or something plays when interacting with the system. Actors are not specific people; the same person can be two actors at different times. A doctor who also borrows books at the staff library is a Doctor in one system and a BookBorrower in the other. Actors are conventionally split into two kinds:

How to identify actors:

Notation convention. Each actor's name is a noun (CamelCase, no spaces), and the actor is documented in one sentence covering its role and how it interacts with the system. For example: "BookBorrower: a member of the library who borrows physical copies of books (Primary)." The description belongs in the requirements document next to the diagram; the diagram itself only carries the name.

A worked actor list, and actor generalisation

Identifying actors is rarely a one-pass job: the first list is usually too coarse or too fine, then it is organised. Reading the Library requirements actor-first yields a fine-grained list of roles, several of which turn out to be the same person:

Candidate actorRole (semantics)
BookBorrowerA member of the library who borrows books only.
JournalBorrowerA member (staff) who borrows books and journals.
BookBrowserSearches for books or journals; may not be a member, and cannot borrow.
BookClassifierClassifies and catalogs new books and registers them in the system.
BookReturnRegistrarReceives returned books and registers them.
BookLendRegistrarLends (or renews) books and registers them.
BookShelverShelves books and records their shelving status.

The last four are all the same human, the Librarian; listing them as separate fine-grained roles first and then grouping them is the normal route to a clean actor. Where one actor can do everything another can and more, the relationship is actor generalisation, drawn with the hollow-triangle inheritance arrow (as in a class diagram), pointing from the specialised actor to the general one. For the Library, the primary-actor hierarchy is:

Generalisation removes repetition: rather than repeating every borrowing association on JournalBorrower, you draw it once on BookBorrower and let JournalBorrower inherit it. This is the actor-side counterpart of the use case generalisation covered below.

Use cases: things actors do with the system

A use case is a task an actor needs to perform with the help of the system. Two rules:

How to find use cases:

How do you know a candidate is a use case, and at the right granularity? Two tests: estimate the frequency of use (something done once at setup may not warrant its own use case); examine the differences between candidate use cases (if two are nearly identical, they may be one use case with alternative scenarios); and distinguish the normal from the alternative course of events (an alternative path is usually a scenario of an existing use case, not a new use case). A use case should be a complete, valuable task from the actor's point of view, not a single click ("enter password") nor a whole subsystem ("manage everything").

Building the diagram from the requirements: noun-verb analysis

The course's standard technique for turning a written requirements document into a first-cut use case diagram is noun-verb analysis. Read the requirements text and mark it up in two colours:

Not every candidate survives. Discard: redundant or omnipotent nouns (a catch-all "system" that does everything), vague entities, meta-language (words about the document rather than the domain), entities outside the system scope, pure attributes, and constraints or events that are not tasks. What remains, read straight off the marked-up text, is the actor list down the side, the use case ellipses in the middle, and the association lines between them. The same noun-verb pass later seeds the class diagram, so it is worth doing carefully.

Worked source text (Library)

"The library contains books and journals; it may have several copies of a book. A library member may borrow for three weeks; members borrow up to six items, staff up to 12; only staff borrow journals. Members of the public can browse / search but cannot borrow. Late returns pay a fine, in cash or by credit card; an email reminder is sent automatically. Staff manage books: add, update, catalog, remove." Bold marks nouns (actors and entities); italic marks verbs (use cases). The credit card and the email pull in the Bank and Email secondary actors, and the verbs become the Borrow / Renew / Return / Browse / Pay fine / Send reminder / Manage use cases on the diagram.

Interactive: build it from the requirements

Step through (or play) the construction of a use case diagram from a short narrative and its user requirements, with each actor and use case traced back to the line it came from.

Relationships between use cases: include, extend, generalisation

Once you have more than a handful of use cases, you will start to see that some use cases share sub-tasks with each other, others fire only in exceptional circumstances, and others are variations on a common theme. UML 2.5 gives three stereotypes for these refinements. Each has a precise meaning and a precise arrow direction, and confusing them is the single most common notation error on this material.

StereotypeSemanticsArrow direction (dashed)Library example
<<include>>Unconditional reuse. The base use case ALWAYS uses the included one as part of its normal flow. The included use case is a sub-task factored out so two or more base use cases can share it, and so it can be changed in one place.From base to included. The base 'knows about' the include.Borrow includes Compute return date; Renew includes Compute return date. Both ALWAYS need a return date.
<<extend>>Conditional alternative. The extending use case fires ONLY IF a guard at a declared extension point in the base is true. Used for alternative or exceptional paths that should not clutter the description of the base.From extending case to base. The extension 'knows about' the base (the OPPOSITE direction from include).Refuse loan extends Borrow when [too many books]. The Borrow flow is unchanged in the normal case; Refuse loan exists only to describe what happens when the guard fires.
Generalisation
(also called <<inherit>> informally)
Specialisation. One use case is a more specific version of another, in the same sense as a subclass. The specialisation inherits the base's behaviour and may override or extend it. Rare; usually a sign that a base use case should be factored.Solid line with a hollow triangle head pointing at the base. From specialised to general (same convention as class generalisation).Pay by credit card specialises Pay fine; Pay by mobile wallet specialises Pay fine. Both inherit the general 'pay fine' workflow but add payment-specific steps.
The directionality rule, stated once

The two arrows go opposite ways and this is the single most-marked notation error. The rule: the arrow tail is on the use case that knows about the other one. With <<include>>, the BASE knows it includes a sub-task (the base description literally contains "include Compute return date" as a step), so the arrow tail sits on the base. With <<extend>>, the EXTENSION knows which base it modifies (the extension description names the base and the extension point), so the arrow tail sits on the extension. Generalisation follows the class-diagram convention: tail on the specialised case, head pointing at the general one.

Worked exampleOnline food ordering: include and extend in a second domain

The Library example shows the mechanics; an online food-ordering app shows the same stereotypes paying back in a different domain.

  • Place order is the primary use case (initiated by the Customer).
  • Calculate order total is <<include>>-d from Place order, and also from Modify order, because both always need the running total (items, delivery fee, tax). It is factored out so the pricing rules live in one place and both base use cases change together.
  • Apply promo code is <<extend>>-ed from Place order, at an extension point "before payment", with guard [has promo]. Most orders carry no promo; the extension keeps the Place order description clean.
  • Refuse order is <<extend>>-ed from Place order, at the extension point "after stock check", with guard [item unavailable]. This is structurally identical to the Library's Refuse loan, and shows the same conditional-alternative pattern recurring across very different domains.

The two stereotypes answer two different needs. <<include>> exists to avoid duplication when two or more base use cases share a sub-task (Calculate order total is shared by Place order and Modify order). <<extend>> exists to keep the base description clean when an optional or exceptional behaviour would otherwise crowd it (Apply promo code and Refuse order only run sometimes; each belongs on a separate ellipse, not as a footnote inside Place order).

External systems are secondary actors

When a use case depends on an external system to do its job, that system is a secondary actor: a payment provider, an SMS or email service, an identity or verification provider, a maps service. Draw it as an actor outside the boundary, with the association running from the use case to it (the use case reaches out to the service to finish its work). It also appears in the use case description's Actors row. The distinction to hold: the primary actor starts the use case for their own goal; the secondary actor is the one the system calls on to complete it.

Generalisation, and all three refinements together

The third refinement, generalisation (informally <<inherit>>), applies when one use case is a more specific version of another. A library borrower can Pay fine in two ways: Pay by cash and Pay by credit card each specialise Pay fine, inheriting its general workflow and adding their own steps. The notation is the class-diagram one: a solid line with a hollow triangle, pointing from the specialised case to the general Pay fine.

The three refinements compose, and a single realistic requirement usually needs all of them. Take the rule "for every successful credit-card payment, send an email confirmation; the bank must approve the payment and may refuse it":

Reuse cuts across this picture: Send message (by email) is factored out as an included sub-use-case shared by both "Send reminder to late loans" (triggered by the SystemTimer) and "Send payment confirmation". One ellipse, two base cases, one change-point. This single Pay-fine picture is the clearest demonstration that include, extend, and generalisation are not academic decorations: all three fall out of one ordinary business rule.

Figure 3b
All three refinements on one diagram: the Library system.
Library SystemBookBorrower(member)JournalBorrower(staff)SystemTimerEmail SystemBank SystemBorrow copy of a bookRenew loan of a bookRefuse loanCompute return datePay finePay by cashPay by credit cardSend reminder tolate loansSend message(by email)Send paymentconfirmationValidate payment<<include>><<include>><<include>><<include>><<include>><<extend>>[too many books]<<extend>><<inherit>><<inherit>>
Read the three refinements off the diagram. The dark dashed <<include>> arrows point from a base case to a sub-task it always uses: Borrow and Renew both include Compute return date, and both Send reminder to late loans and Send payment confirmation include Send message (by email), one shared ellipse with a single change-point. The rust dashed <<extend>> arrows point from a conditional case to its base: Refuse loan extends Borrow under [too many books], and Validate payment extends Pay by credit card (the bank may refuse). The solid hollow-triangle <<inherit>> arrows point from a specialised case to the general one: Pay by cash and Pay by credit card both specialise Pay fine. The three secondary actors (SystemTimer, Email System, Bank System) sit outside the boundary and are reached by plain association, not by a refinement.

Extension points

A common question is "where in the base does the extension fire?" The answer is given by an extension point: a named position in the base's workflow, written in a compartment inside the base ellipse (or in the base's textual description). Borrow copy of a book declares two:

Extension points keep the base's flow auditable: a reader of the base ellipse sees the named hooks and can look up which extensions attach to each. Without them, an <<extend>> arrow is just "this fires somewhere in here", which is too vague to be useful in a contract.

Interactive: the remaining notations

Actor generalisation, use-case generalisation, composite (multi-level) use cases, and extension points, each on a small worked example with a note on when to use it.

When NOT to use these refinements

A diagram with more refinement arrows than associations is over-modelled. Three signs that you are overusing the stereotypes:

When to reach for a composite use case, and a generalised actor

Composite (multi-level) use case. Draw one when a single ellipse stands for a bundle of related tasks that would crowd the top-level page if listed separately. Mark it with the small grid icon and expand it in a lower-level diagram: Manage room inventory becomes Add room, Update rate, Set availability, Remove room; Adel's Manage patient registration becomes Register and De-register patient. Use it to keep the top level readable, not to hide missing analysis: each sub-use-case must still be a real, verb-named task.

Generalised actor. Draw one when two actors share most of their use cases but one is a more capable kind of the other. The specific actor inherits every use case of the general one and adds (or specialises) a few: a Senior Agent is a kind of Support Agent who also handles escalations; a Duty Manager is a kind of Receptionist who can also issue refunds. If the two actors share no use cases, keep them separate; generalisation earns its place only when it removes duplicated associations.

Worked exampleA second domain: the MHC-PMS use case diagram

The Mentcare mental-health patient-management system (MHC-PMS), Sommerville's running example, exercises the same machinery in a different domain. Its actors are the Medical receptionist, Nurse, Doctor, Manager, and the external Patient record system (a secondary actor). Typical use cases: Register patient, Unregister patient, View patient info, Contact patient, Transfer data, View / Edit patient medical record, Setup consultation, Export statistics report, Generate medical report.

One detail is worth singling out, because it is easy to draw wrongly: Transfer data is initiated by the medical receptionist, but its result flows out of the system to the Patient record system. The external records system is therefore a secondary actor: the association line leaves the boundary on the far side of the Transfer data ellipse, with the receptionist on the near side. The receptionist triggers the use case; the records system receives its output. Distinguishing the primary actor who starts a use case from the secondary actor on the receiving end is exactly the kind of thing the diagram exists to make explicit.

Figure 3c
A second domain: the MHC-PMS use case diagram.
MHC-PMSMedicalreceptionistNurseManagerDoctorPatient recordsystemTransfer dataRegister patientUnregister patientContact patientView patient infoExport statisticsreportGenerate medicalreportView patientmedical recordEdit patientmedical recordSetup consultation
Five actors around the MHC-PMS boundary. The Medical receptionist, Nurse, Doctor and Manager are primary actors (they initiate use cases); the Patient record system is a secondary actor, and the single arrowed association out of Transfer data shows the direction of the dependency: the receptionist triggers the transfer, the external records system receives it. Note how one use case can be shared by two actors (View patient info by the receptionist and the manager; View and Edit patient medical record by the nurse and the doctor): a shared use case is drawn once, with an association line to each actor that takes part.

Multi-level (composite) use cases

For larger systems, a single top-level diagram becomes unreadable. The standard pattern is to draw a high-level diagram with composite use cases (each one labelled with a verb phrase like "Manage patient registration"), and to draw a separate first-level diagram for each composite that decomposes it into its constituent use cases. A second-level diagram may decompose a particular first-level use case further, if needed.

A composite use case is marked with a small grid icon to signal that it decomposes further. For the MHC-PMS, three levels are used:

Each level keeps the same system boundary (MHC-PMS) and shows only the actors relevant to that region. Treat the top-level diagram as a map of the system, and each lower-level diagram as a magnified region of that map; decompose only as far as readability requires.

6.UC descriptions

Use case descriptions: the diagram is the index.

A use case ellipse on a diagram is barely a label. The use case itself is fully specified in a structured description. This is the same template the requirements companion uses in Section 6; here it is applied to use cases specifically.

Where it fits

Specification. Each use case ellipse is expanded into a structured description - preconditions, flow of events, postconditions - turning the agreed scope into a testable specification before design begins.

The fields are: System Name, Use Case Title, Description, Actors, Data, Stimulus/Trigger, Pre-conditions, Workflow (or Sequence/Flow of Events), Post-conditions/Response, Comments. Below is the canonical worked example.

System Name: Library System · Use Case Title: Borrow Copy of a Book
DescriptionA BookBorrower may borrow a copy of a book from the library. A book must exist in the library and be available to borrow; it will be issued by the Librarian. The status of the copy of the book will change to <on-loan> and the loan period of the copy will be decided by the type of the book: ShortLoan 2 days, MediumLoan 2 weeks, LongLoan 3 months.
ActorsBookBorrower, Librarian.
DataBook information; borrow information; book status information.
Stimulus / TriggerUser command issued by Librarian on behalf of BookBorrower.
Pre-conditions1. The BookBorrower is a member of the library.
2. The BookBorrower has not already borrowed more than the permitted number of books on loan.
Workflow (sequence of events) 1. The BookBorrower asks the Librarian to borrow a book.
2. The system (or Librarian) checks whether the BookBorrower is allowed to borrow.
3. If yes: 3.1 Librarian records the copy of the book on the BookBorrower's borrowed list; 3.2 Issues the borrowed copy on loan.
4. Else (alternative or error path): the system reports the reason and does not issue the loan.
Post-conditions1. The system has updated the number of books the BookBorrower has on loan, if successful.
2. The copy's loan status is updated to <on-loan>, if successful.
CommentsThe Librarian must have appropriate security permissions to access BookBorrower information.

The same template applied in a different domain, the MHC-PMS "Transfer patient data" use case, shows it is not Library-specific. Note that the external Patient record system appears in the Actors row as a secondary actor, matching the boundary-leaving arrow on the MHC-PMS use case diagram:

System Name: MHC-PMS · Use Case Title: Transfer Patient Data
DescriptionA medical receptionist may transfer data from the MHC-PMS to a general patient-record database maintained by a health authority. The information transferred is either updated personal information (address, phone number, etc.) or a summary of the patient's diagnosis and treatment.
ActorsMedical receptionist, Patient record system (PRS).
DataPatient's personal information; treatment summary.
Stimulus / TriggerUser command issued by the medical receptionist.
Pre-conditions1. The patient is a member of the clinic.
2. The patient information is accessible.
Workflow (sequence of events) 1. The medical receptionist selects the patient records to transfer.
2. The receptionist transfers the selected records to the health authority.
3. If successful: the transfer completes and is acknowledged.
4. Else (alternative or error path): the system reports the failure and no transfer is recorded.
Post-conditions / ResponseConfirmation that the PRS has been updated.
CommentsThe receptionist must have appropriate security permissions to access the patient information and the PRS.

Scenarios: normal, alternative, error

Each time an actor interacts with the system, the triggered use case instantiates a scenario: a specific path through the use case with no branching. Scenarios are typically documented as text alongside the diagram and serve as the readable narratives that customers and testers can confirm against. For each non-trivial use case, expect at least three scenarios:

Worked scenarios for "Borrow copy of a book":

NormalBookBorrower Joe borrows a copy of "Using UML" from the library. Joe has no other books on loan; he takes the copy to the Librarian, who checks Joe's allowance, scans the copy's barcode, and issues the book. The system is updated accordingly.
AlternativeBookBorrower Joe borrows a copy of "Using UML". Joe has no other books on loan. Joe takes the copy to the auto-Librarian kiosk; the kiosk scans his library ID and the barcode on the copy, checks his borrowing allowance, and automatically issues the book to him. The system is updated accordingly.
Error 1BookBorrower Joe brings a book to the Librarian, who checks his allowance and finds that he has six books already on loan (his maximum). The loan is refused; no system update.
Error 2BookBorrower Joe brings a book to the Librarian, who attempts to scan the barcode but finds it damaged. The copy is not issued; the staff log an exception against the copy for replacement.

Notice that the two error scenarios describe quite different failures: one is a business rule violation (too many books), the other is a physical/data integrity issue (damaged barcode). Both are equally valid sources of requirements: the first generates "the system shall enforce a maximum of six items on loan"; the second generates "the system shall provide a manual barcode entry option".

Bridge to the next diagram

A use case ellipse is a label, the description is the contract, and the scenarios are the readable narratives that anchor the conversation with the customer. What none of them captures is the order of work, the parallelism, or the cross-actor coordination that a non-trivial workflow has. That is exactly what the next diagram (the activity diagram) is for. Pick the use case that has the most decisions or the most actors and draw its activity diagram first.

7.Activity diagrams

Activity diagrams: flow, decisions, parallelism.

An activity diagram captures the workflow of a use case or a business process. It is the right diagram when the team needs to talk about the order of work, the decisions that branch the flow, and the activities that can run in parallel.

Where it fits

Requirements analysis. Drawn beside the use case diagram to model the workflow of one use case (or a business process); its decisions and loops later become the alt and loop fragments of the sequence diagram.

 In one line
WhatA workflow as a flow of actions: their order, the decisions that branch them, the work that runs in parallel, and which actor owns each step. It models behaviour and the coordination between activities, and a well-formed one never gets stuck: every path reaches a final node.
HowUnpack a use case description (or a whole business process): steps become actions, choices become a decision closed by a merge, simultaneous work becomes a fork closed by a join, and actions are dropped into swimlanes by actor. Guards in [brackets] on a decision must be mutually exclusive and exhaustive.
WhenWhen a use case has real branching, parallel work, or hand-offs between actors, and as an elicitation tool to see how several use cases combine into one process. Over-engineering for a single linear path of three or four steps.
In this section

The notation: initial and final nodes, actions; decision/merge and fork/join, and how each pair must close; swimlanes (hand-offs) and loops (repeat, retry, guarded exit). Putting it together: unpacking a use case description into a flow; the two granularities (one use case, or a whole business process); and a second worked domain end to end. The goal: take one use case and draw a well-formed flow, decisions closed by merges, forks by joins, every path reaching a final node.

Activity diagrams have a small, fixed vocabulary. Once the symbols are known, the diagram reads like a flow chart with two added powers: it can show parallelism explicitly, and it can assign activities to actors using swimlanes.

Beyond drawing a workflow that is already understood, activity diagrams are an elicitation tool. Drawn during requirements work, they help the team see how use cases interact to achieve a business process, and they frequently surface use cases and operations that the static use case diagram missed. They model the system's behaviour and the dependencies and coordination between activities, and a well-formed one has a property worth checking explicitly: the flow must not get "stuck", every path eventually reaches a final node. Although they are most often drawn for a use case or a business process, an activity diagram can be attached to any model element to describe its dynamic behaviour.

Notation

SymbolMeaning
Filled black circleInitial node. Where the activity starts. Exactly one per diagram.
Filled black circle with ringFinal node. Where the activity ends. There may be more than one.
Rounded rectangleAction (or activity). A unit of work.
DiamondDecision (one input, several outputs with guards) or merge (several inputs, one output). The same symbol is used for both; context disambiguates.
Thick horizontal barFork (one input, several parallel outputs) or join (several parallel inputs, one output).
Vertical columns (swimlanes)Partitions that assign activities to actors, departments, or systems.
Figure 4
Activity diagram with swimlanes: "Collect medical history" (Mentcare). Hover any element for an explanation.
Patient Receptionist Nurse New patient? [yes] Create patient record [no] Search patient record Record personal information Record medical history Medication in menu? [found] Record as code [not found] Record as free text
The diagram shows the activity flow across three swimlanes. Two decision diamonds (with guards in square brackets) split the flow into mutually exclusive branches; matching merge diamonds rejoin them before the next action. The flow starts at the filled black circle in the Patient lane and ends at the bull's-eye in the Nurse lane.
Hover any node, edge, or swimlane to see what it represents.
When System is a lane

A swimlane (UML calls it an activity partition) can represent any participant that performs work, including the software itself, not only human actors. Add a System lane when a step runs with no person in the loop: sending a notification, computing a total or price, persisting a record, or a timer firing an expiry. Put those automated actions in the System lane and leave each human action in the actor's own lane, so the cross-lane arrows still read as the hand-offs between the people and the system. Two faults to avoid: do not drop automated steps into a human lane (it reads as a person doing the machine's work), and do not let one System lane swallow the whole diagram (then the partition tells the reader nothing). Use a System lane when the automated steps are real and worth attributing; omit it at the business-process level, where the focus is the order and concurrency of the work rather than who performs each step.

Interactive: unpack a use case into a flow

Watch the Book room use case become an activity diagram, with each step of its description highlighted as the matching action appears.

Decision vs fork, merge vs join

Two pairs of symbols are routinely confused, and the distinction is the most-marked correctness point on this material. A decision (diamond) chooses one of several guarded branches: its branches are alternatives, and exactly one fires. A fork (bar) starts all of its branches at once: its branches are concurrent. The test is simple. Are the branches a choice (one of them) or parallel work (all of them)? "New patient? create vs search record" is a decision; "place order, then send the confirmation email and update inventory" is a fork, because both happen.

Each opening symbol must be closed by its partner: a decision is closed by a matching merge (the diamond that brings the alternatives back to one path), and a fork is closed by a matching join (the bar that waits for every parallel branch to finish before continuing). An unmatched decision usually means a branch that silently never rejoins; an unmatched fork means concurrency that is never synchronised. Guards on a decision should be mutually exclusive and exhaustive, so exactly one branch is always taken.

A worked fork / join: in a "process order" workflow, the initial node leads to Receive order, then a fork runs two paths in parallel, Fill order (which itself contains a decision, priority vs regular delivery, closed by a merge) and Send invoice then Receive payment. A join waits for both the goods and the payment before Close order and the final node. The fork says both happen; the join says wait for both.

Figure 4b
A fork / join workflow: processing an order.
Receive OrderFill OrderSend InvoicePriority?[priority order][else]OvernightRegularReceive PaymentClose Order
The upper bar is a fork: it starts two paths at once, so filling the order and invoicing proceed in parallel. The left path carries its own decision (priority delivery or not), closed by a merge. The lower bar is a join: it waits for both the goods and the payment before Close Order runs. Replace the fork with a decision and you would assert the system either fills the order or invoices it but never both, a different and wrong claim about the behaviour. Every fork is closed by a join, and every decision by a merge.
Interactive: parallel work and choices

The fork and join for steps that run at the same time, and the merge that closes a decision.

Two granularities: a use case flow, or a whole process

The same notation serves two levels. At the use case level, an activity diagram unpacks one use case ("Borrow copy of a book": locate the book, then fork to stamp the book and record the borrowing in parallel, then join). At the business-process level, it spans several use cases and actors ("book a journey": reserve flight, hotel and car in parallel, with a loop that repeats the car reservation until it succeeds, then confirm). Iteration like that loop, and parallelism like those reservations, are exactly what an activity diagram adds over a numbered list. Keep one granularity per diagram; mixing a single use case and a whole process on one page makes both hard to read.

Figure 4d
Business-process level: Book a journey, composed from several use cases.
Choose trip datesReserve flightReserve hotelReserve carcaravailable?[no][yes]Confirm trip
Here the activity diagram models a whole business process, not a single use case. Reserve flight, Reserve hotel and Reserve car are each a use case in their own right; the process composes them, runs the three in parallel through a fork and join, and wraps a retry loop around the car reservation until one is available. Same notation as the use-case-level diagrams, wider scope. Notice there are no swimlanes here: at the process level the focus is the order and concurrency of the work, not which single system performs each step.

Tying it back: the Library Borrow / Return workflow

The activity diagram for the Library's Borrow and Return use cases pulls together everything in this section: swimlanes for the two actors, a decision, a fork and join for the parallel stamping and record-keeping, and an explicit loop so a member can process several books in one visit. Iteration is the one piece of vocabulary the earlier figures did not need; here the [another book] edge feeds the flow back to the borrow-or-return decision until the member is done.

Figure 4c
Library Borrow / Return: swimlanes, a fork / join, and a loop.
Member Librarian borrow / return? [borrow] Locate copy Stamp book Record borrowing [return] Record book return another? [no] [another book]
The Member chooses to borrow or return; the Librarian does the work. On the borrow path a fork stamps the book and records the borrowing in parallel, rejoined by a join. Both paths reach a merge, then a decision: [another book] loops back to the start so the member can process the next item, and [no] ends the activity. The loop is how an activity diagram expresses "repeat until done"; without it the diagram would describe a single book only.

Loops: repeat, retry, and guarded exit

Loops are how an activity diagram expresses "do this more than once", and they take a few shapes worth recognising, all built from an ordinary decision whose branch points back into the flow:

A retry loop and a guarded exit usually appear together: try, check, and on failure either loop back or, once the attempts run out, leave by a different edge. The case study in the next section draws a retry loop in full.

When to draw an activity diagram

Activity diagrams pay back when the workflow has at least one of: a non-trivial number of decisions, parallel work that the team needs to discuss explicitly, or coordination across multiple actors. They are over-engineering for use cases with a single linear path of three or four steps.

Two practical conventions:

Context

Where activity diagrams earn their place

Problem they solve

Making the order of work visible: where decisions branch the flow, where activities can proceed in parallel, and which actor (or system) is responsible for each step. The forms and forking of work are the most common source of subtle bugs in business and clinical systems; an activity diagram makes them discussable on one page.

Domains where they dominate
  • Business process modelling. BPMN (the Business Process Model and Notation), a UML cousin, is the de facto standard for enterprise workflow tools (Camunda, IBM BPM, Bizagi, Pega).
  • Systems engineering. Activity diagrams in SysML are central at NASA, ESA, Boeing, Airbus, and major automotive OEMs (Toyota, BMW, Daimler).
  • Clinical pathway modelling. NHS Digital and HL7 publish clinical workflows as activity diagrams; the Mentcare-style "collect medical history" example is realistic for this work.
Problems they do not solve

Data structure (use class diagrams), message exchange between objects at the code level (sequence diagrams), or the full state space of a single object (state machine diagrams). Activity diagrams are about flow, not state.

Tooling in current use

Camunda Modeller and Bizagi for BPMN-style enterprise work; Cameo Systems Modeler and MagicDraw for SysML/MBSE; PlantUML and Mermaid for inline-in-Markdown documentation; Lucidchart and draw.io as general-purpose drawing tools.

Documented industrial use. The 2007 NIST report on workflow standards documents how activity diagrams (under various names) became the spine of regulated healthcare workflows. NASA's SysML Modeling Guidelines (2015) prescribes activity diagrams as the primary behavioural artefact for systems engineering. Camunda's published case studies on Deutsche Telekom and ING bank describe BPMN deployments at scale.
Project link. Activity diagrams are most useful at the Phase 3 boundary between requirements and design, when your team needs to settle the cross-actor coordination of a complex use case before drawing class or sequence diagrams. Use them sparingly; one or two activity diagrams covering the most complex flows usually suffices for a project of your size.
Bridge to the next diagram

An activity diagram answers what happens, in what order, and who does it. It says nothing about the objects that carry the activities (the Book, the Loan, the LibraryMember), or the data each one holds. The next section first pulls these two behavioural views together on one small system, end to end; after that, the class diagram captures the static structure those activities run on.

7b.Case study

From requirements to models: a booking system, end to end.

The two behavioural views in this chapter, the use case diagram and the activity diagram, are usually drawn back to back from the same requirements. This case study takes one small system from a short requirements description through to both diagrams, so the bridge between them is concrete. The worked example in section 12 carries a single requirement all the way to a class fragment; here the focus is the two diagrams an analyst draws first.

Stage 1: the requirement description

A boutique hotel wants a small online booking system. From a stakeholder workshop, the analyst captures:

ContextGuests book rooms online; the hotel manager maintains the room list and rates; payments are taken through an external payment provider.
Description"A guest searches for rooms by date and the system shows what is available. The guest picks a room, enters their details and card, and we take the payment through our payment provider; if the card is declined the guest can try again. When payment succeeds we reserve the room and confirm the booking. Guests can cancel a booking, and the manager keeps the room list up to date."

Stage 2: user requirements

The description yields a short set of user requirements (UR), each a complete task from someone's point of view:

UR1A Guest shall be able to search for available rooms by date.
UR2A Guest shall be able to book an available room, paying through the payment provider, and receive a confirmation.
UR3A Guest shall be able to cancel an existing booking.
UR4A Hotel Manager shall be able to maintain the room list and rates.

Reading the nouns and verbs (section 5): the nouns Guest, Hotel Manager, and the external payment provider become actors; "search", "book", "cancel", "maintain", "pay", and "check availability" become candidate use cases; the guest-verb pairings become associations.

Stage 3: the use case diagram

Two primary actors (Guest, Hotel Manager) and one secondary actor (Payment Provider) sit around the boundary. Every booking checks availability and takes payment, so both are <<include>> sub-tasks (Check availability is shared by Search rooms and Book room); a promo code is optional, so it <<extend>>s Book room. Manage room inventory is not one task but several (add a room, update a rate, set availability, remove a room), so it is drawn as a composite use case (the small grid marker) that expands into its own lower-level diagram rather than sitting as one vague catch-all ellipse.

Figure 9b.1
Use case diagram: the hotel booking system.
Hotel Booking SystemGuestHotel ManagerPayment ProviderSearch roomsBook roomCancel bookingManage roominventoryCheck availabilityApply promo codeProcess payment<<include>><<include>><<include>><<extend>>[has promo]
Two primary actors (Guest, Hotel Manager) and one secondary actor (Payment Provider). Check availability is <<include>>d by both Search rooms and Book room; Process payment is <<include>>d by Book room and reaches the Payment Provider; Apply promo code <<extend>>s Book room under [has promo]. The single arrowed association leaving the boundary marks the Payment Provider as the system the use case calls on to finish its work.

Stage 4: the use case description

The central use case, Book room, expands into the template from section 6:

Use Case: Book room (refines UR2)
ActorsGuest (Primary), Payment Provider (Secondary).
Pre-conditionsThe Guest has chosen the dates they want. Availability is not assumed; it is checked inside the flow.
TriggerThe Guest asks to book for those dates.
Workflow (normal)1. Guest selects a room. 2. If the Guest has a promo code, they enter it and the system applies the discount (optional, the Apply promo code extension). 3. Guest enters their details and card. 4. System requests authorisation from the Payment Provider. 5. On approval, the system reserves the room. 6. The booking is confirmed and the authorised payment is captured.
Alternative / errorBefore booking, if no room is available the flow ends without a booking (the early final node). At step 4, if the card is declined the Guest re-enters payment details and the request is retried; no booking is made until a payment is approved.
Post-conditions(a) On success: a reserved booking exists and is confirmed. (b) On failure: no room is reserved.

Stage 5: the activity diagram

The same Book room flow, drawn as an activity diagram, makes the order of work, the decisions, the retry loop, and the hand-off to the external provider explicit. Swimlanes assign each step to the Guest, the Booking System, or the Payment Provider.

Figure 9b.2
Activity diagram: the Book room flow, with a retry loop, a parallel fork/join, and an external provider.
GuestBooking SystemPayment ProviderSearch roomsFind available roomsroomsavailable?[no][yes]Select roomhas promo?[yes]Enter promo code[no]Enter payment detailsAuthorise paymentapproved?[approved]Reserve roomConfirm bookingCapture payment[declined]: retry payment
Three swimlanes assign each step to the Guest, the Booking System, or the Payment Provider. The [rooms available?] decision either ends the flow (no rooms) or continues; the cross-lane arrow to Authorise payment is the hand-off to the external provider; the optional [has promo?] decision is the activity form of the Apply promo code extend, a guarded branch that merges straight back; the [declined] branch is the retry loop, returning to Enter payment details until a payment is approved; on the [approved] branch the room is reserved, then a fork runs Confirm booking and Capture payment in parallel before a join merges them. Two final nodes: one for "no rooms", one for a confirmed booking.
Modelling convention: the system is not an actor

The diagram above gives the system under development its own Booking System swimlane. That is a common industrial style, but Adel's convention is not to model the system being built as an actor or a partition. The reason is the same one that makes the system the boundary rather than an actor in a use case diagram: an activity diagram already describes the behaviour of the system, so a lane named after the system is redundant and blurs the line between the system and the outside parties it serves.

Partitions should name the external participants whose responsibilities differ: the human roles that provide input or make decisions, and the external systems the flow hands off to. The system's own automated steps are just the actions of the activity, drawn without a dedicated lane. Figure 9b.3 redraws the same Book room flow on that principle: the two external parties (the Guest and the Payment Provider) are named in the actions that touch them, and every other action is the system's own behaviour.

Figure 9b.3
The same flow without a system swimlane: the system's steps are the activity itself; only the external parties are named.
Find available rooms roomsavailable? [no] [yes] Receive room choice (Guest) Request authorisation (Payment Provider) approved? [declined]: retry [approved] Reserve room Confirm booking (Guest) Capture payment (Provider)
No partition is named after the system. The Guest and the Payment Provider appear only inside the actions that touch them (Receive room choice, Request authorisation, Confirm booking, Capture payment); every other action is the system's own work. The control flow is identical to Figure 9b.2: the [rooms available?] early exit, the [declined]: retry loop back to authorisation, and the fork/join that confirms the booking and captures the payment in parallel. If the workflow had crossed several human roles (a receptionist, a manager), those roles would be the swimlanes; the system itself never is.

Read it against the description and every action traces back to a workflow step or an alternative path. The use case description and the activity diagram describe the same behaviour at two levels: the description in words, the diagram in flow.

What the bridge shows

One short description produced four artefacts in sequence: user requirements, a use case diagram, a use case description, and an activity diagram. Each adds precision the previous one left implicit: the diagram names the actors and tasks, the description pins down the steps and conditions, and the activity diagram fixes the order, the decisions, and the loop. Drawing them in this order is the everyday rhythm of the analysis stage.

8.Class diagrams

Class diagrams: the system's static structure.

A class diagram shows the classes in a system and the associations between them. It is the longest-lived diagram on most projects, because the static structure changes more slowly than any particular flow through it.

Where it fits

System & object design (structure). The static structure of the system's entities, derived from the noun analysis of the requirements; the longest-lived model, refined from analysis level through to design.

Classes, not instances. A class diagram shows the types in the system, Book, LibraryMember, the kinds of thing that can exist, not the particular copy on the shelf or the member at the desk. To show specific instances at one moment (this member, that copy, with concrete values) you draw an object diagram, the section immediately after this one.

 In one line
WhatThe classes the system knows about, their attributes (data) and operations (behaviour), and the associations, with multiplicity, that connect them. In early analysis a class is a real-world thing: a patient, a prescription, a book.
HowMostly bottom-up from the requirements by noun-verb analysis: nouns and roles become classes and attributes, verbs become operations, and the noun-verb pairings become associations. Then add multiplicity, generalisation for is-a, aggregation or composition for part-of, and association classes for attributes that belong to a relationship.
WhenWhenever an object-oriented model is built; it is the central structural deliverable and the one teams design against. Not for the order operations run in (sequence or activity), an object's lifecycle (state machine), concurrency, or deployment.

Where the classes come from: three design approaches

Before any class is drawn you decide how to decompose the system. Adel's notes name three classic strategies; analysis-level work usually blends them, but it helps to know which one you are leaning on.

In analysis we work mostly bottom-up from the requirements, using the noun-verb method below, and sanity-check it against a top-down view of the whole. The goal is classes justified by the text, not by the developer's imagination.

Reading a class out of the other diagrams

A class box has three compartments, and each maps to something the behavioural views already produced. This is the bridge from behaviour to structure: the name compartment comes from an actor or entity, the attributes from the data the use cases touch, and the operations from the use cases that object performs. Every part of a class should be answerable to an earlier model.

Figure 5a
Each compartment traces back to a behavioural model (actor/entity, the data a use case stores, the use cases it provides).
Patient + name: String + dateOfBirth: Date - record: PatientRecord + register() + viewRecord() + bookAppointment() An actor or entity a person, role or thing theuse case diagram identified The data it must store becomes the attributes The use cases / services it provides become theoperations (methods)
The class box is not invented from scratch: its three compartments map onto work you have already done. That traceability keeps the structural model in step with the requirements.

Anatomy of a class box

Figure 5
A UML class, in full notation
Book + title: String + ISBN: String - copyCount: int # publisher: String + isAvailable(): boolean + reserve(m: LibraryMember): void + addCopy(c: BookCopy): void - updateStatus(): void Name compartment Attributes compartment Operations compartment Visibility + public - private # protected ~ package / derived e.g. /age is computed from birthDate
A class has three compartments: name (top), attributes (middle), operations (bottom). Each attribute and operation carries a visibility marker. UML 2.5 defines five visibility symbols; the three most common are +, -, and #.

Visibility, in full

UML's visibility markers map directly to access modifiers in mainstream OO languages, with one or two extra options:

Fuller attribute and operation notation

An attribute's full form is visibility name : type [multiplicity] = default {property} and an operation's is visibility name(parameter : type, …) : returnType {property}. Beyond plain name-and-type, a few further markers are worth recognising:

Figure 5b
The fuller notation in one class: an identifier, a derived value, a multi-valued attribute, a class-scope member, a constructor, and a query.
Account + accountNo : String {id} + /balance : Money + holders : Person [1..*] totalAccounts : int «constructor» + create(o : Owner) + deposit(amount : Money) + getBalance() : Money { query }
accountNo is the identifier ({id}); /balance is derived; holders is multi-valued ([1..*]); totalAccounts is underlined, so it is class-scope (one value shared by the class, not one per object); create is the «constructor»; getBalance is a {query} that does not change state. An abstract class would show its name in italics.

Relationships: associations, generalisation, aggregation

Figure 6
Class diagram with associations, multiplicity, generalisation, and aggregation (Library)
LibraryMember + memberId: String + name: String + register() StaffMember + department: String + role: String Book + ISBN: String + title: String + catalog() BookCopy + barcode: String + status: LoanStatus 1 1..* has copies 0..1 0..6 borrows / returns Loan + startDate: Date + returnDate: Date + extend(): void
Four relationships are shown: generalisation (StaffMember to LibraryMember; closed triangle pointing at the parent), aggregation (Book contains BookCopy; open diamond at the whole), association with multiplicity (LibraryMember borrows BookCopy; 0..1 to 0..6), and an association class (Loan; attached to the borrows association line with a dashed link at the line's midpoint).

Multiplicity, in detail

Multiplicity on an association end answers: how many instances of this class can participate in the relationship at one time? Standard values:

NotationMeaning
1Exactly one.
0..1Optional: zero or one.
* or 0..*Zero or more.
1..*One or more.
m..nAt least m, at most n. Example: 3..7.
mExactly m. Example: 5.

Aggregation vs composition

Both denote "part of" relationships, but with different lifetime semantics:

Modern style is to avoid aggregation where composition would do, because aggregation is semantically weak: most tools and reviewers cannot distinguish it from a plain association. Composition, by contrast, has bite.

Association classes

When an association itself has attributes that do not belong to either of the connected classes, those attributes live on an association class. Example: a Loan between a LibraryMember and a BookCopy has its own startDate and returnDate; these are attributes of the borrowing relationship, not of the member or of the copy. The association class is drawn as a regular class box, connected to the association line by a dashed link.

Ternary and n-ary associations

Most associations are binary: they link two classes. A ternary association links three classes at once, and an n-ary association links n; it is drawn as a diamond with one line to each participating class. Like a binary association, a ternary association can carry its own data on an association class, attached to the diamond by a dashed link. Adel's example: a Player plays for a Team in a given Year; the facts that depend on all three together (goals scored, games played that season) belong to none of the three alone, so they live on an association class hung off the diamond.

Figure 6g
A ternary association (Team, Player, Year) with an association class.
Team Year Player PlayerSeasongoals : intgamesPlayed : int * * * plays-in
The diamond joins all three classes; the dashed link carries the association class PlayerSeason, whose attributes describe one (Team, Player, Year) combination. Each end's multiplicity (here *) is read for a fixed value of the other two participants. Use ternary associations sparingly: if the link can be expressed as an intermediate class joined to each participant by ordinary binary associations, that is usually clearer (and is required if a participant can appear more than once). Reach for the diamond only when the three-way link is irreducible.

Data-driven noun-verb analysis

The standard recipe, introduced by Shlaer and Mellor in the late 1980s, is the noun-verb analysis: read through the requirements document and underline every noun phrase; collect those noun phrases as a candidate class list; discard inappropriate ones (redundant, omnipotent, vague, meta-language, outside the system scope, or are attributes of something else); then identify every verb and assign verbs to candidate classes as operations. The result is a first-cut class diagram that is grounded in the requirements you wrote, rather than the developer's imagination.

Six categories of "inappropriate" noun, worth memorising because they recur in reviews of analysis-level class lists:

Heuristic categories from Booch's Object-Oriented Analysis and Design for which nouns make good classes:

Analysis classes vs design classes

An analysis class abstracts one or more classes of the eventual design; it models the problem domain, not the solution. Conceptually it carries responsibilities, domain-level attributes, and the relationships it takes part in. The first-cut analysis class diagram, though, is drawn as a deliberate skeleton: classes, associations and multiplicities only, with no attributes and no methods. It fixes the domain's vocabulary and structure before any commitment to data or behaviour. Detail is added in two later steps: attributes when the analysis model is fleshed out, then method signatures, types, tightened visibility, infrastructure classes (persistence, controllers, factories), patterns and navigability when it becomes a design class diagram.

Analysis vs design: draw the one asked for

The two forms are asked for separately, and each task names which it wants. An analysis class diagram shows classes, associations and multiplicities only, no attributes and no methods (that is the skeleton in Figure 6a). A detailed or design class diagram shows the full boxes: attributes and method signatures, with types and visibility. Putting attributes or operations on an analysis class diagram has jumped ahead to design; leaving them off a detailed class diagram is under-specified. Read the instruction and draw exactly that form.

Worked exampleThe Library, by noun analysis

Adel's running example. Underline the nouns in the requirement, then sift them.

The library contains books and journals. It may have several copies of a given book. Some of the books are for short-term loans only. All other books may be borrowed by any library member for three weeks. Members of the library can normally borrow up to six items at a time, but members of staff may borrow up to 12 items at one time. Only members of staff may borrow journals. The system must keep track of when books and journals are borrowed and returned.

Candidate classes kept: Book, BookCopy, Journal, LibraryMember, StaffMember. Discarded or demoted: Library (the system itself), item (vague), three weeks / six / 12 (loan period and limits: attributes and multiplicities, not classes).

Noun-verb analysis gives candidates, not answers. For each one you argue keep, reject, or it depends, and the reasoning matters more than the verdict:

CandidateDecisionWhy, and the alternative rejected
bookclassThe work itself (ISBN, title). Not merged with its copies because one title has many physical copies and you lend a copy, not the title.
copyclassThe physical item (barcode, status). Keep only Book and you cannot say which of three copies is on loan; BookCopy is the fix.
journalclass (debatable)Kept separate because journals follow staff-only loan rules. Alternative: Book and Journal both specialise an abstract LibraryItem, tidier if more item types arrive.
itemreject, but…Too vague to be a class, yet it is the hint for that LibraryItem superclass. A rejected noun can still shape the model.
loan / borrowingassociation classLooks like a verb, but it carries its own data (start and return dates) belonging to the member-copy pairing, not to either alone: the Loan association class.
member, staffclass + generalisationStaff is-a member, so generalisation. Alternative: if one person can be both at once, model a Role rather than a subclass.
libraryrejectThe system boundary, not a domain object, unless the requirements track several libraries.
three weeks, six, 12rejectLoan period and borrowing limits: attributes and constraints (multiplicities), not classes.

The principle: a good class list is defended, not asserted. Be ready to say why BookCopy earns its place and library does not, to name the alternative you considered (the LibraryItem superclass, the Role class), and why you set it aside.

Figure 6a
First-cut analysis class model, derived from the Library description.
LibraryMember StaffMember Book BookCopy 1 1..* has copies 0..1 0..6 borrows / returns Loan
A first-cut analysis class diagram, the form Adel labels the “class model (analysis classes)”: the kept nouns become named boxes, joined by the relationships and multiplicities the analysis has argued for, and nothing else is drawn. No attributes, no methods, no types. That is deliberate: the analysis diagram fixes the domain's vocabulary and structure before any commitment to data or behaviour. The relationships are themselves analysis decisions: Staff is-a member is a generalisation; a Book has copies is an aggregation (1 to 1..*); a member borrows copies is an association (0..1 to 0..6) whose data will live on the Loan association class. Attributes are added when the model is fleshed out, and method signatures when it becomes a design class diagram (the design-level figures below show that fuller form). Asked for an analysis class diagram, draw exactly this: classes, associations and multiplicities, with no attributes or methods. Hover any box, line or diamond for what it is.

What makes a good analysis class

Five criteria, drawn from Cooper, Larman, and the broader OO design literature, that practitioner reviews look for:

Associations: direction, roles, and reflexive links

Name an association with a verb phrase and read it in a direction. A plain line is bidirectional; an arrowhead makes it unidirectional (the tail class can reach the head class, but not the reverse). An association connects classes (the type level); a link is one instance of it between two specific objects (Adel: links instantiate associations).

Figure 6b
Bidirectional vs unidirectional association.
Patient PatientRecord has bidirectional access flows both ways Book BookCopy is a copy of 11..* unidirectional a Book reaches its copies,not the other way
A Patient and PatientRecord know each other (bidirectional); a Book points to its BookCopy but not the reverse (unidirectional). The arrowhead is navigability: which way access can travel.
Figure 6c
Role names, and a reflexive association.
Company Person employs 1employer 0..*employee Role names each end can be labelled with therole that class plays in the link Employee manages manager 0..1 subordinate 0..* Reflexive (self) association a class related to itself: one Employeemanages many, each managed by one
An association end can name the role each class plays, and a class can associate with itself: an Employee manages other Employees. Reflexive associations are how hierarchies (manager/report, folder/subfolder) are modelled.

Generalisation: the substitutability test

Draw generalisation only for an is-a relationship. The test is substitutability: anywhere the code expects a LibraryMember you can hand it a StaffMember and nothing breaks. Wrong: "Car is-a Engine", a car is not a kind of engine, it has one, so that is an association (Car has Engine). Right: "ElectricCar is-a Car". If the substitution would be absurd (an Engine where a Car is expected), it is not generalisation.

A subclass inherits every attribute and operation of its superclass and may add its own; the inherited members are never repeated on the subclass. The arrow is a hollow triangle pointing at the parent. Below, Hospital doctor and General practitioner are both kinds of Doctor: each inherits Doctor's name, phone, email and the operations editRecord() and viewRecord(), and adds only what is specific to it.

Generalisation and inheritance
Subclasses inherit the parent's members and add their own (Doctor hierarchy).
Doctor name, phone, email editRecord() viewRecord() Hospital doctor staffNo : String pager : String General practitioner practice : String address : String
One hollow triangle points at the parent; the shared line then branches to the subclasses. Both subclasses inherit Doctor's name, phone, email, editRecord() and viewRecord() (not redrawn on them) and add their own members. This is the same generalisation already used in the Library model (StaffMember is a LibraryMember); shown here on its own so the inheritance of members is explicit.

Multiple inheritance

A class may specialise more than one parent at once: multiple inheritance, drawn as one generalisation arrow to each parent. Adel's example: a Professor is both a Tutor and a Researcher, inheriting the attributes and operations of both. Use it with care, because it raises name-clash and repeated-ancestor questions and several programming languages forbid it; at the analysis level it is valid when the subclass truly is both.

Multiple inheritance
A Professor is both a Tutor and a Researcher.
Tutor Researcher Professor
Two generalisation arrows (each a hollow triangle pointing at the parent) make Professor a subclass of both Tutor and Researcher. Professor inherits the members of both; if both define a member of the same name, the clash must be resolved, which is why multiple inheritance is used sparingly.
Figure 6d
Aggregation (hollow diamond) vs composition (filled diamond).
Team Employee 13..* Aggregation (hollow diamond) weak part-of: an Employee outlives the Team House Room 11..* Composition (filled diamond) strong part-of: destroy the House and its Rooms go too
Both say part-of; they differ in the lifetime of the part, and the diamond always sits at the whole. A Team aggregates Employees (they outlive the team); a House is composed of Rooms (destroy the house and the rooms go too). Prefer composition where it fits: aggregation is semantically weak. Adel's examples: a Course is part of a Programme (and may sit in more than one); an Airplane is made of Assemblies made of Components, so aggregation can recurse; a chessboard is composed of exactly 64 Squares.
Worked exampleA second domain: the MHC-PMS

Adel's other running example, from Sommerville's mental-health-care patient management system. It shows a different shape: one central, attribute-rich class, Consultation, that anchors the whole model.

Figure 6e
MHC-PMS: a central Consultation class between Patient and Doctor.
Patient + name: String + dateOfBirth: Date + patientId: String Doctor + name: String + staffId: String Consultation + date: Date + time: Time + clinic: String + reason: String + medicationPrescribed: String + treatmentPrescribed: String + voiceNotes: String + new() + prescribe() + recordNotes() + transcribe() 1 1..* attends 1..* 0..* conducts
The most important class in a model is often not an actor but a central event or interaction. Consultation's attributes are the data one consultation records; its operations are what a doctor does during one (prescribe, recordNotes). The two associations read straight from the sentence "a doctor conducts a consultation that a patient attends".

What a class diagram can contain: classes, data types, enumerations, and dependency

A class diagram is not limited to classes. It shows three kinds of box, each carrying a stereotype where it is not an ordinary class, and several kinds of line between them.

The lines are the relationships. The associations (plain, aggregation, composition) and generalisation were covered above. The weakest is the dependency: a dashed line with an open arrowhead, meaning a transient "uses" link. A class depends on a data type or enumeration it references in an attribute or an operation, and on another class it takes as a method argument; the difference from an association is permanence. An Order that holds Products over time has an association to Product, but an Order whose total is a Money value, or that passes a Product to one method, only depends on those types.

Figure 6f
Dependency, an enumeration, and a data type.
Order+ total : Money Product+ type : Category «enumeration»CategoryBookMusicVideoSoftware «dataType»Moneyamount : intcurrency : String «use» «use» «use»
Order and Product are classes. Money is a «dataType» (a value made of an amount and a currency) and Category is an «enumeration» (a fixed list of values). The three dashed, open-headed arrows are dependencies: Order's total is a Money, so Order depends on Money; Product's type is a Category, so Product depends on Category; and Order uses Product as a method argument. None of these is a permanent has-a link, so each is a dependency, not an association.

Cohesion: high versus low

Most weak class models fail on cohesion or coupling. The test is simple: count the reasons to change. A low-cohesion Patient that also sends reminder emails, generates PDF reports, connects to the database and calculates insurance has four reasons to change; touch the email server and you risk breaking billing. A high-cohesion Patient does one job (be a patient) and moves the rest to a NotificationService, a ReportGenerator, a PatientRepository and an InsuranceCalculator, so it changes only when what it means to be a patient changes. Fewer reasons to change is higher cohesion.

Context

Where class diagrams earn their place

Problem they solve

Capturing the static structure of an object-oriented system: which classes exist, what they contain, and how they are connected. The class diagram is the longest-lived diagram on most projects because the static structure changes more slowly than any particular flow through it.

Domains where they dominate
  • All object-oriented software. Java, C#, Python, TypeScript codebases of any non-trivial size benefit from a class-diagram view.
  • Domain modelling. Domain-Driven Design (Evans 2003) uses class diagrams as the canonical artefact for the ubiquitous language.
  • ORM mapping. Hibernate, Entity Framework, Django ORM, ActiveRecord all map class diagrams to relational schemas.
  • Design patterns. The Gang of Four's Design Patterns (Gamma et al., 1994) communicates every pattern as a class diagram.
Problems they do not solve

Runtime behaviour (use sequence or state diagrams), concurrency (no concept of threads or processes), data flow (use activity diagrams), or deployment topology (use deployment diagrams). A class diagram tells you what exists; it tells you nothing about what happens.

Tooling in current use

IDEs (IntelliJ IDEA, Eclipse, Visual Studio) reverse-engineer class diagrams from code automatically. PlantUML and Mermaid render text descriptions to diagrams in Git workflows. Lucidchart, Visual Paradigm, and Enterprise Architect support full forward and reverse engineering.

Documented industrial use. The Eclipse Modeling Framework (EMF), Java's RMI, and Spring Framework's bean configuration are all class-diagram-driven at the architectural level. Microsoft published the Office class hierarchy as a reference example for many years. Google's protocol buffers and gRPC service definitions correspond directly to class-diagram structures, even when expressed in text.
Project link. The class diagram is the central deliverable of your Phase 3 design submission. Aim for an analysis-level class diagram with 8 to 15 classes from the noun-verb analysis of your Phase 2 requirements; reserve the deeper design-level class diagrams (with full method signatures, design patterns, and infrastructure classes) for Phase 4 or the implementation phase.
Bridge to the next diagram

The class diagram tells you what exists; it tells you nothing about what happens. A method borrow() on LibraryMember might involve calls to Book, BookCopy, Loan and PersistenceStore in a specific order, with possible authorisation checks and error returns. That story (messages over time between a fixed cast of objects) is what the sequence diagram captures. Pick the use case scenario whose call chain is least obvious and draw that sequence diagram next.

8b.Object diagrams

Object diagrams: a snapshot of the running system.

A class diagram shows the types; an object diagram shows specific instances of those types and the links between them at a single moment. Adel introduces it immediately after the class diagram, because the quickest way to test a class model is to populate it with real objects and see whether everything fits.

Where it fits

System & object design. A snapshot used to validate the class model; drawn in the same phase as the class diagram, by instantiating it with concrete objects to check every value has a home and every link a matching association.

 In one line
WhatA snapshot: specific objects (instances of your classes) and the links (instances of associations) between them at one moment, with each attribute set to a concrete value.
HowTake a class diagram and instantiate it: draw a box per object with an underlined name : Class header and an attribute = value line for each attribute; join objects that are linked. Show no operations and no attribute types.
WhenDuring analysis and design, to validate the class model against real data: a concrete snapshot quickly exposes a missing class, a wrong multiplicity, or an attribute with nowhere to live.

What an object diagram is

Objects are instances of classes. An object diagram captures objects and the relationships between them, that is, instances of classes and the links (instances of associations) between them. It is built during analysis and design to illustrate data and object structures, to specify snapshots of the system at a point in time, and above all to validate the class model, asking whether the classes are sufficient to hold the data and support the methods the system needs. Analysts, designers and implementers all draw them.

Notation: the object icon

An object box has a name compartment and an optional attribute compartment. The name is written objectName : ClassName and is underlined (this is what distinguishes an object from a class); each attribute is shown as attribute = value. Crucially, operations and attribute types are not shown on an object diagram: it is about concrete data at one instant, not behaviour.

When the instance-of link itself must be made explicit, for example drawing an object next to its class, UML uses a dependency stereotyped «instantiate» from the object to the class it is an instance of (or from a link to the association it instantiates). Inside a pure object diagram this is left implicit; the stereotype is simply the formal name for “is an instance of”.

Figure 6h
The object icon: an underlined name and concrete attribute values.
DSRsUMLBook : Booktitle = "Using UML"name compartmentattribute = valueobject name : Class name (underlined)Operations and attribute types are NOT shown on object diagrams.
An object names its class and pins each attribute to a value. Compare with a class box, which shows attribute types and an operations compartment; an object box shows neither.
Worked exampleA class model and its snapshot: SmartSoft

Adel's running example pairs a class diagram with one object diagram that instantiates it. First the class model: a Company is composed of Departments and Offices; a Department is located at an Office and can contain sub-departments (a reflexive composition); a Person works at a Department and one Person manages it (a subset of works-at); a Headquarter is a kind of Office; and a Person depends on ContactInformation.

Figure 6i
Detailed class diagram: Company, Department, Office, Person (after Adel).
Companyname: StringDepartmentname: StringOfficeaddress: Stringphone: IntegerHeadquarterCEO: StringPersonname: StringemployeeID: IntegercontactInfo: ContactInformationprocessOrder()confirmOrder()answerQuery()«dataType»ContactInformationaddress: StringtelNo: Integer1..*1..*1located at**(subset)0..1*works at1..**manages1
Six relationships, and one point about what may appear on a class diagram. Composition (filled diamonds at Company and at Department); an association with multiplicity (located at, * to *); a reflexive composition on Department (the {subset} constraint marks manages as a subset of works at); two associations from Person to Department (works at, and the navigable manages, open arrowhead); a generalisation (Headquarter is an Office, hollow triangle); and a dependency (dashed, open arrow) from Person to ContactInformation. That last box is not a class but a «dataType» - a value type with no identity of its own, like Address or Money. Class diagrams legitimately show classes, data types and enumerations (each stereotyped), which is why ContactInformation appears here: it is the type of Person's contactInfo attribute, and the dependency records that Person uses it.

Now one snapshot of that model: the company "Smart Software", with its actual departments, office, an employee, and his contact record. Every box is an instance of a class above; every value is concrete; no operations appear.

Figure 6j
Object diagram: a snapshot of SmartSoft instantiating the class model above.
SmartSoft : Companyname = "Smart Software"d1 : Departmentname = "R&D"d2 : Departmentname = "Sales"nsales : Departmentname = "North Sales"ssales : Departmentname = "South Sales"BZUBranch : Officeaddress = "Birzeit"phone = "0097059..."HeadquarterCEO = "Dr Munir"p1 : Personname = "Sameer"employeeID = 1233ContactInformationaddress = "1 Marj St, Birzeit"telNo = "0097259..."located atworks atmanages
SmartSoft : Company is composed of d1 : Department (R&D) and d2 : Department (Sales, itself composed of North and South Sales), and of BZUBranch : Office. d1 is located at the branch; p1 : Person (Sameer) works at and manages it; the branch is a Headquarter; and p1 uses a ContactInformation record. Building this snapshot is how you check the class model holds together: each value has a home, each link has a matching association.
Worked exampleA second snapshot: the Library

The same idea against the Library class diagram from the previous section: one member, one copy, one borrowing link.

Figure 6k
Object diagram: one library member borrowing one copy.
adel : LibraryMembermemberId = "M-1007"name = "Adel" copy42 : BookCopybarcode = "BC-42"status = onLoan borrows
adel : LibraryMember is linked to copy42 : BookCopy, one link of the member-borrows-copy association. A snapshot like this validates the class model: building it with real data exposes a missing class, a wrong multiplicity, or an attribute that has nowhere to live.
In practice

An object diagram is the cheapest test of a class diagram. If you cannot draw a plausible snapshot, the class model is wrong somewhere: an attribute with no box to sit in, a link the associations do not allow, or a multiplicity the data violates. Draw one whenever a class model feels abstract or a multiplicity is in doubt.

Bridge to the next diagram

A class diagram and its object snapshot are both static: a structure and one frozen instant of it. The next diagram, the sequence diagram, sets those same objects in motion, showing the messages they exchange over time.

9.Sequence diagrams

Sequence diagrams: the order of messages.

A sequence diagram shows one specific interaction: who sends what message to whom, in what order. Time runs top to bottom; participants are arranged left to right. Unlike a class diagram, which captures the system at rest, a sequence diagram captures the system in motion.

Where it fits

System & object design (interaction). Realises one scenario of a use case as a timed exchange of messages between objects; it is a live check on the class diagram, since every message it sends must be an operation that class declares.

Instances, and one scenario at a time. The lifelines are instances (objects), written : Class (anonymous) or name : Class, never bare classes, because a sequence diagram shows real objects exchanging messages on one run. And one diagram tells one story: a single scenario of a single use case. Draw the normal (happy) path first as an instance diagram; fold the alternatives and errors in with combined fragments (alt, opt, loop), or draw them as separate diagrams (the generic diagram). Do not try to cram every path into one picture.

 In one line
WhatThe interaction for one scenario of one use case: which participant sends which message to whom, in what order, with arguments, and when each participant is active (the activation bars). Time runs top to bottom; participants sit left to right.
HowPick one scenario; place the initiating actor and then the collaborating objects (instances of your classes) across the top; drop a dashed lifeline from each; add messages in time order, naming the operation each calls; draw activation bars and dashed returns; wrap any choice or repetition in a fragment (alt, opt, loop).
WhenFor a scenario whose call order is not obvious, or a collaboration that needs pinning down: a checkout, an authorisation, a booking. Not for static structure (class diagram), an object's whole lifecycle (state machine), or every scenario at once (one diagram is one story).

Where the participants and messages come from

A sequence diagram invents nothing. It realises one scenario of a use case, using the classes from the class diagram and calling their operations:

In the sequence diagramComes from
The scenario being drawnone path through a use case (its normal flow, or one alternative)
The participants (lifelines)actors and objects; the objects are instances of classes from the class diagram
The messagesthe operations declared on those classes
The fragments (alt, loop)the decisions and loops of the activity diagram for that use case

Consistency check. If a lifeline receives a message fetchRecord(), the class it instantiates must declare fetchRecord(). The sequence diagram is therefore a live check on the class diagram: a message with no matching operation means the class model is incomplete.

Figure 7a
Notation legend: lifelines and activation bars, and the message kinds.
: Caller : Receiver 1: doRequest() - synchronous call (solid, filled head) 2: validate() , self-message return result , reply (dashed, open head) 3: notify() , asynchronous (solid, open head) activation bar = busy
The box names the participant (: Class for an anonymous object, name : Class for a named one); the dashed lifeline drops from it; the thin activation bar marks the time it is busy. Message kinds: synchronous (filled head, the caller waits), reply/return (dashed, open head), and asynchronous (open head, solid line, fire and continue). A message back to the same lifeline is a self-message. Actors do not get an activation bar: an external participant (the Customer in the Deposit Cash example, the Librarian in the next one) sits outside the system, so we do not model its internal execution, it only sends and receives messages. Only the system objects that execute a message are barred.

One scenario, or all of them: instance vs generic

Adel draws the distinction clearly. An instance diagram is one concrete run, no branching, the happy path: quick to draw, ideal for explaining the normal flow. A generic diagram shows the family of runs using combined fragments (alt, opt, loop) to fold the alternatives and repetitions into one picture. Rule of thumb: draw the instance first to nail the normal flow, then promote it to a generic diagram only where real branching or looping matters. Do not cram every error path into one diagram; that is what fragments, or separate diagrams, are for.

A generic diagram with an alt fragment

Figure 7 promotes an instance to a generic diagram: the authorisation decision is folded into one picture with an alt fragment, exactly the notation the legend above introduces. Solid arrows are synchronous calls, dashed open-headed arrows are returns, and the guard after each branch label decides which one fires.

Figure 7
Sequence diagram: "View patient information" with alt fragment for authorisation
: Doctor : UI : AuthService D: PatientRec 1: requestView(patientId) 2: authenticate(token) alt [authorised] 3: return authorised = true 4: fetchRecord(patientId) 5: return record 6: display(record) [else] 3': return authorised = false 4': showError("not authorised")
The alt fragment encloses two alternative behaviours separated by a horizontal dashed line. The guard in square brackets after each branch label indicates which one fires. Solid arrows are synchronous calls; dashed arrows with open heads are returns.

UML 2.0 fragments, in detail

UML 2.0 added interaction fragments to make sequence diagrams expressive enough for non-trivial flows. The five most common operators:

OperatorMeaning
altAlternative paths. Two or more branches separated by dashed horizontal lines, each labelled with a guard. Exactly one branch executes per execution of the fragment.
optOptional behaviour. Executes only if the guard is true. Equivalent to an alt with a single branch.
loopThe fragment may execute zero or more times. The guard indicates the iteration condition. Optionally loop(n) for exactly n times.
parParallel execution. Two or more branches execute concurrently; the order between them is not defined.
refReference to another sequence diagram. Used to avoid drawing the same sub-interaction repeatedly across diagrams.
Figure 7d
The five combined fragments, with a one-line example of each.
alta : Ab : Balt[ok]approve()[else]exactly one branch runsopta : Ab : Bopt[vip]applyDiscount()runs only if the guard holdsloopa : Ab : Bloop[more]addItem()runs 0+ times while guard holdspara : Ab : BparsendEmail()updateLog()both branches run concurrentlyrefa : Ab : BrefAuthenticatereuse another diagram (named)in one linealt: many guarded branches, one fires.opt: a single optional branch.loop: repetition.par: concurrency.ref: a reusable sub-interaction.
alt picks one of several guarded branches (here [ok] vs [else]); opt is a single branch that runs only if its guard holds; loop repeats while its guard holds; par runs its regions concurrently (order between them unspecified); ref stands in for a named sub-interaction drawn elsewhere. Use alt/opt for choice, loop for repetition, par for concurrency, ref for reuse.
Worked exampleThe "Deposit Cash" scenario

Adel's self-service-machine example, the normal scenario. Three internal objects do the work: the front (the customer interface), the register (where money is counted and the cash reserve kept), and the dispenser (which delivers the receipt).

Figure 7b
The “Deposit Cash” scenario: Customer, Front, Register and Dispenser.
: Customerfront : UIregister : Register: Dispenser1: insertMoney(amount)2: makeSelection(acct, amount)3: sendMoney(amount)4: checkAmount()5: updateReserve()6: deliverReceipt()confirmation7: ok8: showConfirmation()
Read it top to bottom: each solid arrow is a synchronous call to an operation that exists on the receiver, and each dashed arrow is the return that hands control back. The activation bar on each lifeline covers exactly the time that participant is busy.
Worked exampleThe Library "Borrow a copy" scenario

The same Library modelled earlier with a use case, an activity diagram and a class diagram, now in motion for one scenario. The lifelines are objects of the classes LibraryMember, BookCopy and Loan; the messages are their operations; the alt is the activity's "limit reached?" decision.

Figure 7c
Borrowing a copy, with an alt on the loan limit and a «create» message to a Loan object.
: Librarianm : LibraryMemberc : BookCopy1: borrow(c)2: checkAllowance()alt[within limit]3: issue()onLoan: Loan4: «create» new(m, c, today)5: loan recorded[limit reached]6: loan refused
The Librarian calls borrow(c) on the member m; m runs a self-message checkAllowance() to check the six-item limit. alt [within limit]: m calls issue() on the copy (which returns onLoan), then creates a new Loan object (the «create» message, whose lifeline begins where it is created), and returns "loan recorded". alt [limit reached]: m returns "loan refused" and nothing is issued or created. Every message targets an operation that exists on that class, and the Loan object's dates are set at creation, exactly the association class from the class diagram. What the : Loan box is: a newly-created instance - an anonymous object of the Loan association class. A «create» message points at the new object's box (not a lifeline), which is why the Loan sits lower down and its lifeline begins at that point; there is no reply arrow because the object now existing is the result of the message. It is idle for the rest of this scenario, so it carries no activation bar.
How to build one

Recipe. (1) Pick one scenario of one use case, starting with the normal flow. (2) Place the participants across the top: the actor that starts it, then the objects it collaborates with. (3) Drop a lifeline from each. (4) Add messages in time order, top to bottom, naming the operation and its arguments. (5) Draw activation bars for the time each participant is busy, and the dashed returns. (6) Wrap conditional or repeating parts in fragments.

Sanity checks. Every received message is an operation that exists on the receiver's class; every synchronous call has a matching return; time only goes down (no arrow points back up the page); one diagram is one scenario, branch with fragments rather than tangling two stories together.

Pitfalls

Step through a sequence diagram

The interactive below plays a sequence diagram one message at a time. Use it to see how activation bars grow and shrink as messages flow.

Sequence-diagram player

"Buy a drink" at a vending machine: front UI, vending controller, dispenser. Step through to see each message and the activation bars it grows.
Step 0 of 7
: Customer front : UI controller : Vending : Dispenser
Press Next to begin. The customer initiates the purchase by inserting money into the front of the machine.
Context

Where sequence diagrams earn their place

Problem they solve

Pinning down the order of messages between objects, components, or services in one specific scenario. Sequence diagrams catch race conditions, missing returns, forgotten error paths, and unrealistic latency assumptions before code exists.

Domains where they dominate
  • Protocol design. IETF RFCs document OAuth 2.0 flows, TLS handshake, HTTP/2 negotiation, and Kerberos exchange as sequence diagrams.
  • Distributed systems and microservices. Distributed-tracing tools (Jaeger, Zipkin, OpenTelemetry) reconstruct sequence-style views automatically from production traces.
  • API documentation. Stripe, Twilio, AWS publish sequence diagrams for their authentication and webhook flows.
  • Safety-critical systems. Avionics and medical-device standards require sequence-level traceability of interactions.
Problems they do not solve

Static structure (use class diagrams), the full set of states an object can be in (use state machines), the workflow of a long-running business process (use activity diagrams), or system topology (use deployment diagrams). A sequence diagram captures one path through one scenario; do not try to capture the whole system in one.

Tooling in current use

PlantUML and Mermaid are now the dominant tools for text-driven sequence diagrams in API documentation and Git workflows. swimlanes.io is popular for ad-hoc sketches. WebSequenceDiagrams and SequenceDiagram.org cover dedicated diagramming. Distributed-tracing systems (Jaeger, Zipkin) generate sequence-like views from runtime data.

Documented industrial use. RFC 6749 (OAuth 2.0) and RFC 7235 (HTTP authentication) document their core flows as sequence diagrams. Stripe's developer documentation uses sequence diagrams to describe payment-intent webhooks. The OpenTelemetry specification (CNCF) is itself a sequence-diagram-driven model of distributed tracing. Fowler's UML Distilled (3rd ed.) calls sequence diagrams "the most useful UML behavioural diagram" for working teams.
Project link. For your Phase 3 deliverable, draw sequence diagrams for two or three non-trivial use cases (typically the ones with the most actors or the most alternative paths). Each sequence diagram refines a use case from the use-case diagram and feeds the design of the corresponding methods in the class diagram. Do not try to draw a sequence diagram for every use case; that is over-engineering.
Bridge to the next diagram

A sequence diagram is a horizontal cut: one scenario, many objects. The next diagram is the vertical cut: one object, many scenarios over its lifetime. The state machine asks "what states does this object pass through, and which events cause which transitions?", which is the question you should be asking about a Loan, an Order, or any other object whose behaviour depends on its current state.

9b.Communication diagrams

Communication (collaboration) diagrams: the same interaction, drawn as a structure.

A communication diagram shows the very same message exchange as a sequence diagram, but it drops the time axis and keeps the links between participants instead. Order is recovered from numbered messages rather than from vertical position. UML 1.x called this a collaboration diagram; UML 2.x renamed it a communication diagram; Adel uses the two names interchangeably.

Where it fits

System & object design (interaction). The same object interaction as the sequence diagram, with a structural emphasis; it checks that every message rides on a link that exists as an association in the class diagram.

 In one line
WhatOne scenario's interaction laid out as a graph of participants joined by links, with each message written on the link it travels along and a sequence number giving its order. The emphasis is who is connected to whom, not elapsed time.
HowPlace the objects (and the initiating actor) anywhere on the page; draw a link (a plain line) between any two that exchange a message; write each message along its link as number: operation(args) with a small arrow for direction; use nested (Dewey) numbering - 1, 2, 2.1, 2.1.1 - to show which call happens inside which.
WhenWhen the point is which objects are linked and how the work fans out across them, rather than the precise timeline. For most teams the sequence diagram has won; communication diagrams survive for small interactions and for checking that links match the class diagram's associations.

Notation: links, messages, and Dewey numbering

A communication diagram has only three ingredients:

Figure 7e
Notation: two linked objects and a numbered message.
a : Caller b : Receiver 1: doRequest(x) the line is the link; the arrow + number is the message
The plain line between a and b is the link (an instance of an association). The short arrow over it, labelled 1: doRequest(x), is the message; its number fixes the order. Add * for repetition and [guard] for a condition.

Same scenario, two diagrams: Deposit Cash

Here is the exact interaction from the Deposit Cash sequence diagram above, redrawn as a communication diagram. Nothing about the behaviour changes; only the emphasis does. The vertical timeline becomes a set of links, and the order that was implicit in the descent down the page is now carried by the message numbers. The nesting (2.1.1, 2.1.2, 2.1.3) shows that the register's work all happens inside the call it received.

Figure 7f
“Deposit Cash” as a communication diagram - the structural twin of Figure 7b.
: Customer front : UI register : Register : Dispenser 2: makeSelection(acct, amount) 1: insertMoney(amount) 2.1: sendMoney(amount) 2.1.1: checkAmount() 2.1.2: updateReserve() 2.1.3: deliverReceipt()
Same participants, same messages, same order as Figure 7b - but the timeline is gone and the links carry the story. The Dewey numbers (2.1, 2.1.1, …) encode the call nesting the sequence diagram showed by descending position. Each link is an instance of an association: Customer-front, front-register, register-Dispenser - if a message had no association to ride on, the class model would be missing a relationship. Reading the numbers: they give the order of execution - 1 fires first, then 2; a decimal suffix marks nesting, so 2.1 is the first call made inside message 2, and 2.1.1 then 2.1.2 run inside 2.1. On each link the plain line is the association the message travels on; the small arrow beside it shows only the message's direction. Hover any participant, link or message for what it represents.

Sequence vs communication: when to reach for which

 Sequence diagramCommunication diagram
Emphasistime - the order of messagesstructure - the links between participants
Order shown byvertical position, top to bottommessage numbers (1, 2, 2.1…)
Reads well forlong flows, many steps, alt/opt/loop fragmentssmall interactions; checking links match associations
Weak atshowing the network of who-talks-to-whomlong sequences; control flow gets cramped

The two are formally interchangeable for a single scenario: any communication diagram can be redrawn as a sequence diagram and vice versa, because they hold the same information. Choose by the question you are answering. In modern practice the sequence diagram dominates; the communication diagram is worth knowing because it makes the link-to-association correspondence visible, and because it still appears in older designs.

Where it earns its place. Reach for a communication diagram in one situation: to show, for a single scenario, which objects are linked and how the work fans out across those links, and to check that every link is an instance of an association in the class diagram. It does not scale to long or branch-heavy flows (use a sequence diagram) and its numbered messages become unreadable past a dozen steps. Naming note: UML 1.x called it a collaboration diagram, UML 2.x renamed it a communication diagram; both are the same structural re-projection of the sequence diagram, and most tools convert between the two automatically.

Project link. You are not asked to submit communication diagrams for the project, but drawing one for a single use case is a fast way to confirm that every message in your sequence diagram travels along a link that exists as an association in your class diagram. A message with no association to ride on means the class model is missing a relationship.
10.State machines

State machine diagrams: the object's life.

A state machine diagram captures the states an object passes through during its lifetime and the events that cause transitions between them. It is the right diagram whenever a class has a meaningful "current state" that callers must reason about.

Where it fits

System & object design (behaviour). Models one object's lifecycle - the states it passes through and the events that move it between them - drawn for the classes that have a meaningful current state (a Loan, an Order, a BookCopy).

Where it fits, and at what stage. A state machine describes the lifecycle of the instances of one class (a Loan, an Order, a BookCopy), so it is drawn at the design stage, after the class diagram has identified a class whose behaviour is state-dependent, the same call doing different things, or being illegal, in different states. Like the class diagram it is object-focused and long-lived; unlike a sequence diagram, which shows one scenario across many objects, a state machine shows one object across its whole life. Most classes never need one, reach for it only when an object's allowed operations change with its state.

 In one line
WhatThe complete lifecycle of one object (or one system): the finite set of states it can occupy, the events that move it between them, and the actions those moves trigger. It answers "what can happen to this object, and when is each operation legal?".
HowIdentify the distinct states (each a condition in which the object behaves differently); draw one initial pseudostate and the final state(s); for every state ask which events are legal and where each leads, labelling transitions event [guard] / action; attach entry/exit/do activities where behaviour belongs to the state itself; nest related states into a composite state when the picture grows.
WhenWhen an object's behaviour depends on its current state (the same call does different things, or is illegal, depending on state), or it has a real, observable lifecycle (Loan, Order, Ticket, Account). Not for passive data carriers, value objects, or pure functions.

Notation

Figure 8
State machine: the lifecycle of a BookCopy
Availableentry / shelve()OnLoando / countDays()Overdueentry / notifyMember()Lostentry / chargeFee()borrow()return()after(3 weeks)[overdue]return()reportedLostreportedLost
Five named states, one initial, one final. Each transition has an event (and sometimes a guard). The Overdue state has an entry action; the OnLoan state has a do activity that continues while the state is active. A copy that is reported lost transitions directly to the terminal Lost state.

The smallest machine: a turnstile, and self-transitions

The canonical example is a coin-operated turnstile with two states, Locked and Unlocked. It is small enough to force the central question of state modelling: what does every event do in every state? A coin in Locked unlocks it; a push while Unlocked locks it again. But a push while still Locked, or a second coin while Unlocked, must also be answered: here by a self-transition, an event that fires an action but leaves the object in the same state (the loop back onto the state).

Figure 8b
The turnstile: two states, and a self-transition for each "ignored" event.
Locked Unlocked coin / unlock push / lock push / alarm coin / thanks
Two states answer every event in both: a coin unlocks, a push locks; a push when already Locked sounds the alarm and a coin when already Unlocked just thanks the user, both self-transitions that act without changing state. A self-transition (the loop) leaves and re-enters the state, so it re-runs the state's entry and exit actions; an internal transition (written as a line inside the state box) handles the event without leaving, so entry/exit do not fire. Choose the self-transition when the event should reset the state, the internal one when it must not.

Theoretical foundations: from finite automata to statecharts

A state machine is a finite-state automaton: a finite set of states, an alphabet of events, and a transition function mapping a (state, event) pair to a next state. It is the oldest and most rigorously understood model of behaviour in computing, which is why the same idea drives compilers, network protocols and control systems.

Events, guards, actions, activities: the full vocabulary

A transition label has the form event [guard] / action, and each part is precise:

Composite, orthogonal, and history states

These are the statechart extensions that keep a real diagram readable. A composite state contains a nested sub-machine; a transition out of it applies to all its sub-states at once, so you draw the shared cancel arrow once rather than from every sub-state. Orthogonal regions, separated by a dashed line inside a composite state, are active simultaneously: independent concerns modelled as two regions need 2 + 2 states, where flat modelling needs 2 × 2, and the gap widens fast. A history pseudostate (a circled H) remembers which sub-state was active when the composite was last left, so re-entry resumes there: it is how a "resume" feature is modelled.

Figure 8a
A composite state with two orthogonal regions, and a shared exit (Order processing).
Active payment region fulfilment region AwaitingPayment pay() Paid Picking packed Packed H cancel Cancelled
Inside Active, two orthogonal regions run at once: payment moves AwaitingPayment→Paid while, independently, fulfilment moves Picking→Packed. The circled H is a history pseudostate, re-entry resumes the fulfilment region where it left off. The single cancel transition leaves the whole composite from any combination of sub-states, which is the economy a flat machine cannot offer.

When to draw a state machine

State machines pay back when at least one of the following is true:

Most classes do not need a state machine. Data carriers, value objects, and pure functions have no state in this sense. Drawing a state machine for them is over-engineering. Conversely, every domain object whose lifecycle is meaningful (Order, Loan, Ticket, Patient, Account) is a candidate.

Where it earns its place. A state machine pays off when an object's allowed behaviour depends on its current state, so a reviewer can ask “is there a state where this event does nothing?”, “is any state unreachable?”, “can it get stuck?”. It dominates in embedded and safety-critical systems (engine control, pacemakers; MATLAB Stateflow under DO-178C / ISO 26262), network protocols (TCP's state machine in RFC 793), UI state management (Harel statecharts, XState), and domain-object lifecycles (order, loan, ticket). It does not model interactions between objects (sequence diagram), static structure (class diagram), or workflow across actors (activity diagram): it is about one object's life.

In practice. Most systems have one or two domain objects with a meaningful lifecycle (a Loan, an Appointment, an Order, a Booking). Draw a state machine for each of those. Drawing one for a passive data class (e.g., a Patient record) is usually unnecessary; if you find yourself drawing it, ask whether the lifecycle is about the record or about something else (the consultation, the registration).
Bridge to the next diagram

State machines, sequence diagrams, class diagrams and activity diagrams all describe what one application does. The remaining question is what the application is made of and where it runs. That is the territory of the architectural diagrams (component for build-time structure, deployment for run-time topology), covered next.

Simulate the BookCopy state machine

The interactive below runs the BookCopy state machine. Fire events with the buttons and watch the current state change, with guards enforced.

State machine simulator

The BookCopy lifecycle. Only the events that are legal in the current state are enabled; the rest are greyed out, so every click you can make fires a real transition. Hover any state to read its entry / do / exit actions, and hover the guarded transition to see where the guard sits.
state: Available
Availableentry / shelve()OnLoando / countDays()Overdueentry / notifyMember()Lostentry / chargeFee()borrow()return()after(3 weeks)[overdue]return()reportedLostreportedLost
Reading the notation: inside a state, entry / do / exit name its actions - entry and exit run once on the way in and out, while do runs the whole time the object is in the state. On a transition, the label reads event [guard] / action: the guard in square brackets must be true for the transition to fire. Here after(3 weeks) is a time event and [overdue] is its guard.
Initial state: Available. Only the events legal in this state are enabled; click one to fire its transition.
11.Component & deployment

Structural architecture: components and deployment.

Component and deployment diagrams sit higher up the abstraction ladder than the diagrams above. They are concerned with how the system is partitioned at build time and how it is distributed at run time.

Where it fits

Design & system design (architecture). The component diagram is the build-time architecture/component view; the deployment diagram is the run-time execution view - the last structural models, mapping the system onto modules and onto the nodes they run on.

 In one line
WhatStructure at two higher levels: a component diagram shows the build-time parts (modules or services) and the contracts (provided and required interfaces) between them; a deployment diagram shows the run-time topology, which artefact runs on which node and over which protocol.
HowFor components: group cohesive classes into a component, expose what it offers as a provided interface (lollipop) and what it needs as a required interface (socket), and wire one component's socket to another's lollipop. For deployment: draw each execution node as a 3D box, place the artefacts that run on it inside, and join nodes with labelled communication paths.
WhenOnce the system is non-trivially partitioned (several modules or services) or distributed (more than one machine or tier). These are the views operations and infrastructure engineers read; for a single-process toy they are over-engineering.

Component diagrams

A component diagram shows the structural relationships between the major components of a system. A component in UML 2 is a modular part of the system with well-defined interfaces. Components offer two kinds of interface:

A provided lollipop fits into a matching required socket; the connection is valid if the socket's required operations are a subset of the lollipop's provided operations and their signatures are compatible.

When a required socket and a provided lollipop are wired between two components, a dependency arrow is drawn along the connection as well: it leaves the requiring socket and its arrowhead meets the provider's lollipop, the same dashed dependency notation used on a class diagram. The arrow direction records who depends on whom; the consumer depends on the provider.

What a component is, in theory

A component is a modular, replaceable unit of the system that hides its implementation behind well-defined interfaces. Its defining property is substitutability: anything that offers the same provided interfaces can replace it without the rest of the system noticing. That single idea is what makes plug-ins, device drivers and microservices possible.

Figure 9
Component diagram with provided/required interfaces (Order example)
Order <<component>> CustomerRepository <<component>> Inventory <<component>> CustomerLookup ProductLookup
Components carry the <<component>> stereotype and the small component icon (the two-rectangle glyph). The socket (half-circle) on Order is a required interface; the lollipop (●) on each provider is a provided interface; the dashed dependency arrow runs from the requiring socket to the provider's lollipop (Adel's convention, the same dependency notation as on a class diagram), labelled with the interface name (CustomerLookup, ProductLookup). Hover any socket, lollipop or arrow for what it is.

Componentisation guidelines

Ports and delegation: building a large component from smaller ones

A port is a named interaction point drawn as a small square on a component's boundary; it groups the interfaces offered and needed at that point, so the outside world wires to the port rather than to the component's insides. A delegation connector then forwards the port inward to the internal part that actually implements it, and an assembly connector joins one inner part's required interface to another's provided interface. Ports plus delegation are how a big component presents one clean boundary while being built from smaller ones.

Figure 9a
A composite component: a port and a delegation connector on the boundary, an assembly connector inside. Hover any glyph for what it means and the messages it carries.
OrderSystem <<component>> : OrderHandler <<component>> : Billing <<component>> port OrderEntry <<provided>> <<delegate>> <<required>> Charging assembly connector Interface operations (the messages carried on the lines): OrderEntry · + placeOrder(items) + cancelOrder(orderId) Charging · + charge(amount) + refund(orderId)
Five notations, each shown once. (1) A port (small square on the boundary) groups what is offered or needed at one interaction point. (2) A provided interface (lollipop, ●) is a service offered, here OrderEntry. (3) A delegation connector (<<delegate>>) forwards the port inward to :OrderHandler, the part that implements it. (4) A required interface (socket, the cup) is a service a part needs: :OrderHandler needs Charging. (5) An assembly connector joins that required interface to :Billing's provided Charging. The operations listed at the foot are the actual messages each interface carries. Hover any glyph for its meaning and its messages.
Worked exampleA component diagram: the seminar-registration system

Adel's running architectural example is a university seminar-registration system, and it is the clearest way to see the componentisation guidelines applied: user-interface logic goes in <<UI>> components, each business concept becomes its own domain component, and the cross-cutting technical concerns (security, persistence) become shared <<infrastructure>> components. Reading top to bottom is reading the layers of the architecture.

Figure 9b
Seminar-registration system: UI, business-domain, and infrastructure components.
UI layer business / domain layer infrastructure layer Seminar Management <<UI>> Student Administration <<UI>> Seminar <<component>> Schedule <<component>> Student <<component>> Security <<infrastructure>> Persistence <<infrastructure>> University DB <<database>> manageSeminars manageStudents DataAccess <<JDBC>>
Three layers, read top to bottom. The two <<UI>> components depend on the business-domain components (Seminar, Schedule, Student); those depend on the shared Persistence infrastructure component (the DataAccess interface); persistence reaches the <<database>> over <<JDBC>>. Security is a cross-cutting infrastructure component (its AccessControl lollipop is used by every layer; the wiring is omitted to keep the figure readable). This same component set is allocated to nodes in the deployment diagram below.

Deployment diagrams

A deployment diagram shows the runtime configuration of the system: which software runs on which hardware (or virtual) nodes, and how the nodes connect. It is the right diagram when the system is non-trivially distributed.

Notation:

Nodes, artefacts, and manifestation

Deployment has a small vocabulary worth getting exactly right:

Figure 10
Deployment diagram: 3-tier web application
PC Client <<pc client>> <<component>> Browser Web Server <<server>> <<artifact>> seminar.war DB Server <<database>> <<artifact>> university.db <<HTTPS>> <<JDBC>>
A typical 3-tier deployment: the client hosts the browser; the web server hosts UI and application components; the database server hosts the persistence component and the database. Communication paths are labelled with their protocols.

Choosing the tiers: 2-tier, 3-tier, 4-tier

The same set of components can be deployed onto different numbers of nodes, and that choice is itself a design decision with consequences for security, performance and cost. Adel draws the seminar system three ways; the trade-off is what to put where:

LayoutWho hosts whatTrade-off
2-tierClient + one server that runs both the application and the database.Simplest and cheapest; the database is exposed on the application server, and the single server limits scale and isolation.
3-tierClient / application (web) server / separate database server.The common web layout: the database sits behind the application tier (better security), and each tier scales on its own, at the cost of an extra hop and node.
4-tierAdds a dedicated security/gateway (or caching) node in front of the application tier.Strongest isolation and a single enforcement point for authentication; more infrastructure to run and a longer request path.

The lesson Adel draws from this: a deployment diagram is not a transcription of the component diagram - the same components can be allocated to nodes in several ways, and the allocation is where security, performance and operational cost are actually traded off.

Three shapes worth practising: co-location, redundancy, and shared servers

Three configurations recur in deployment questions and are worth being able to draw without hesitation. First, two logical servers on one physical machine: draw two <<executionEnvironment>> nodes nested inside one <<device>> node (a wording like “the web server and the database server are physically located on one hardware server” is asking for exactly this). Second, redundancy for availability: a standby node that replicates the primary, joined by a <<replication>> path, is how a deployment delivers the availability goal. Third, several unlike clients sharing the same servers: two different <<device>> clients (say a tablet app and a browser) both reach the one server. The figure below shows all three at once.

Figure 10a
Co-located servers, a redundant backup, and two clients sharing them. Hover any node or path.
<<device>> Tablet AdminApp <<device>> PC Browser <<device>> Campus Server <<executionEnvironment>> Web Server <<artifact>> seminar.war <<executionEnvironment>> DB Server <<artifact>> university.db <<JDBC>> <<device>> Backup Server <<artifact>> web + DB replicas standby / failover <<HTTPS>> <<HTTPS>> <<replication>>
All three shapes on one diagram. Co-location: the Web Server and DB Server are two <<executionEnvironment>> nodes nested inside the one <<device>> (Campus Server), which is how a single physical machine running two logical servers is drawn. Redundancy: the Backup Server device replicates them over a <<replication>> path, the deployment move that delivers availability. Shared servers: a Tablet and a PC, two different <<device>> clients, both reach the web server over <<HTTPS>>. A hardware-software mapping question is answered by exactly these pieces: devices, nested execution environments, the artifacts they host, and labelled communication paths.
Same component, two platforms

One case is worth spelling out because it looks like a contradiction and is not. Suppose the same client is offered as an iOS app and an Android app. That is two separate <<device>> nodes, not one: each runs a different operating-system execution environment (the OS is itself a container), and each holds its own executable artifact, built differently for that platform. What they share is the logical component they realise (the same UI), not the node or the artifact. So “an app on iOS and Android” maps to two device nodes, each with its own OS execution environment and its own executable, both manifesting one component.

Architectural styles and the 4+1 view model (layered, client-server, peer-to-peer, three-tier/four-tier, MVC, repository, pipes-and-filters, SOA) belong to architectural design and are developed in full in the Chapter 5 System Design companion. A deployment diagram like the one above is an instance of an architectural style; choosing the style, and trading off the quality attributes that drive that choice, is the subject of that chapter.

These two structural views complete the diagram set. Each UML diagram is a different projection of one system, and the use cases are the thread that checks the projections agree: the same point Sommerville makes with his four perspectives (context, interaction, structural, behavioural). The framework that organises these projections into named architectural viewpoints, Kruchten's 4+1 view model, is developed in the Chapter 5 System Design companion.

Context

Where component and deployment diagrams earn their place

Problem they solve

Component diagrams answer "what are the major moving parts and how do they connect?". Deployment diagrams answer "where does each part actually run and what does it talk to?". Both are architectural views that operations and infrastructure engineers, not application developers, are the primary consumers of.

Domains where they dominate
  • Enterprise architecture. TOGAF, the Open Group Architecture Framework, prescribes component-and-deployment diagrams as core artefacts of every reference architecture. ArchiMate (the TOGAF modelling language) overlaps heavily with UML's component view.
  • Cloud architecture. AWS Architecture Diagrams, Azure Reference Architectures, and Google Cloud's reference designs all use deployment-style notation with cloud-vendor icons.
  • Microservices documentation. Component diagrams document service boundaries and provided/required interfaces; deployment diagrams document Kubernetes node topology.
  • Compliance and audit. ISO 27001 and SOC 2 audits typically require an "infrastructure diagram" that is a deployment diagram with regulatory labels (where personal data sits, where audit logs go).
Problems they do not solve

Internal class structure of a component (use a class diagram), runtime behaviour of a component (use sequence diagrams), or workflow across components (use activity diagrams). Component diagrams stop at the interface boundary; what happens inside is a separate concern.

Tooling in current use

Lucidchart, draw.io, and the AWS / Azure / GCP architecture-icon libraries dominate cloud work. Structurizr (by Simon Brown, of Software Architecture for Developers) is a text-driven tool aligned with the C4 model, a modern simplification of UML's structural diagrams. ArchiMate tooling (Archi, BiZZdesign) for enterprise architecture.

Documented industrial use. Bass, Clements, and Kazman's Software Architecture in Practice (4th ed., 2021) is the standard reference; SEI (Software Engineering Institute) publishes case studies on industrial component and deployment work, including the U.S. Department of Defense and large healthcare systems. Simon Brown's C4 model (2018) is the most widely adopted contemporary simplification of UML's structural and architectural views for working software teams. Netflix's published architecture overviews (on netflixtechblog.com) use deployment-style diagrams throughout.
In practice. An architecture document typically carries one component diagram (the major modules and the interfaces between them) and one deployment diagram (where each module runs and how clients reach it). Both stay at the conceptual level; neither commits to deployment manifests.
12.Worked example

From elicitation to first-cut model: one requirement, all the way through.

The earlier sections cover each diagram in isolation. This section walks one user requirement from the elicitation interview to a first-cut design, showing the substance at each step. The example is intentionally small so the full trace fits on this page; on a real project, every requirement goes through this same chain.

Stage 1: Elicitation snippet

In a structured interview with the head librarian of the Birzeit Main Library, the analyst captures the following extract (paraphrased to the level of detail an interview transcript would record):

SourceInterview with M. Hamdan, Head Librarian, 14 March.
Question"Walk me through what happens when a student borrows a book."
Answer (paraphrased)"The student brings the copy to the desk. We scan the barcode and pull up their record. If they already have six items out, we refuse the loan, they have to return something first. If they're clear, we record the loan with a due date that depends on the book: short loans are two days, medium loans two weeks, long loans three months. The student keeps the copy and a small printed slip with the due date."
Follow-up question"What if the barcode is damaged or unreadable?"
Answer"We type it in manually and log an exception so the copy gets a replacement barcode next week."

Notice what the interview transcript already contains, even before any modelling: an actor (BookBorrower, called "the student"), a sub-actor implied (Librarian, the speaker), a business rule (max six items), a domain rule (loan periods depend on book type), a normal flow, an exception (damaged barcode), and an alternative outcome (loan refused). The analyst's job in the next stage is to write that down in a form that survives months of execution.

Stage 2: User Requirement (UR) and System Requirements (SR)

The transcript converts into one UR with two SR refinements. The numbering follows the convention used in Ch.3 section 3.

UR3A library member shall be able to borrow up to six copies of books at one time, with the loan period determined by the book type (short, medium, or long loan).
SR3.1The system shall enforce a maximum of six concurrent loans per LibraryMember. An attempt to record a seventh loan shall be refused, and the BookBorrower shall be informed of the reason at the point of refusal.
SR3.2The system shall compute the return date for each Loan as: start date + ShortLoan(2 days) | MediumLoan(2 weeks) | LongLoan(3 months), based on the BookCopy's parent Book's type field.
SR3.3If the BookCopy's barcode is unreadable, the system shall allow manual entry by an authorised Librarian and shall raise a damaged-barcode exception for review.

Each SR is a developer-precise refinement of UR3 (note the shared prefix). Each is testable: SR3.1 corresponds to a test case for the seventh-loan refusal, SR3.2 to a parameterised test of the three loan periods, SR3.3 to a manual-entry test plus exception verification.

Stage 3: Effort estimate for UR3

Using the per-UR method from Ch.3 section 9, the team estimates UR3 as follows. The estimate is in person-weeks (pw); the calculator in Ch.3 takes these numbers and rolls them up into the project total.

Concurrent developers2 (one full-stack on the front end and persistence; one specialist on the barcode integration)
Effort per developer1.5 person-weeks (covers SR3.1 enforcement, SR3.2 date logic with three branches, SR3.3 manual-entry handler and exception logging, plus tests)
Total effort for UR33 person-weeks (rolled into the project total)

This estimate is what the customer is asked to authorise. If the customer later asks for "also support overdue notifications", a new UR is added, re-estimated, and added to the project total before any work begins.

Stage 4: Use case ellipse and description

UR3 maps to one primary use case (Borrow copy of a book) plus its refinement use cases (Compute return date as <<include>>, Refuse loan as <<extend>>). The diagram form is in figure 3 above; the textual form, expanded into the eight-field template used throughout section 6, looks like this:

Use Case: Borrow Copy of a Book (refines UR3)
DescriptionA BookBorrower borrows a copy of a book from the library; the Librarian processes the loan. The copy's status moves from Available to OnLoan and a return date is computed.
ActorsBookBorrower (Primary), Librarian (Primary).
Pre-condition(a) BookBorrower is a registered member. (b) BookBorrower has fewer than 6 items on loan. (c) The BookCopy is in state Available.
TriggerBookBorrower presents the copy to the Librarian.
Workflow (normal)1. Librarian scans the copy's barcode. 2. System retrieves the BookCopy and its parent Book. 3. System counts BookBorrower's current loans. 4. System invokes Compute return date (using Book.type to choose ShortLoan, MediumLoan, or LongLoan). 5. System creates a Loan(start_date, return_date, copy, member). 6. BookCopy.status becomes OnLoan. 7. Librarian hands the copy and printed slip to BookBorrower.
Alternative workflowAt step 3, if currentLoans == 6, invoke Refuse loan (the <<extend>> at the "maximum no. of items on loan" extension point); inform BookBorrower; no Loan is created.
Error workflowAt step 1, if the barcode is unreadable, Librarian enters the barcode manually; a damaged-barcode exception is logged against the BookCopy (SR3.3).
Post-condition(a) On success: a new Loan exists; BookBorrower's loan count is +1; BookCopy.status == OnLoan. (b) On refusal: no system state change.

This textual description is the contract; the ellipse on the diagram is the index entry. The activity diagram (Stage 7) draws this workflow in swimlanes for the BookBorrower and the Librarian, the two actors who do the work; the system's automated steps surface inside the desk actions the Librarian drives, not as a lane of their own, which is the caution section 7 raises about system lanes. The sequence diagram (Stage 9) draws the messages that cross the design classes when the Librarian's scan reaches the entities.

Stage 5: First-cut class fragment

From the noun-verb analysis of the UR / SR text (section 8): nouns LibraryMember, Book, BookCopy, Loan, Librarian; attributes loan count, status, barcode, start_date, return_date, type; verbs borrow, return, compute return date, refuse. At this stage only the classes, their relationships, and the multiplicities go on the diagram, exactly as in figure 6a: the attributes and verbs just listed are noted for the design step, not drawn. The first-cut fragment for UR3 is:

Figure 11
First-cut analysis fragment for UR3 (Borrow copy of a book): classes, associations, multiplicities, nothing else.
LibraryMember BookCopy Book 0..1 0..6 borrows Loan 1..* 1 has copies
The analysis form, exactly as figure 6a defines it: named boxes, the relationships, and the multiplicities, with no attributes and no operations. LibraryMember borrows BookCopy with multiplicity 0..1 to 0..6 (a copy is on loan to at most one member; a member holds at most six copies, directly encoding SR3.1). Loan is an association class (dashed link to the borrows line): the loan's dates will belong to the member-and-copy pairing, not to either class alone. Book aggregates BookCopy, so the open diamond sits at the Book end, the whole: one Book (1) has one or more copies (1..*), and copies survive the deletion of the catalogue record, which is why this is aggregation rather than composition. What analysis withholds (types, visibility, operations) arrives in Stage 6.

Three observations worth taking away from the fragment:

Stage 6: Design classes (analysis to design)

The first-cut model in Stage 5 is an analysis fragment. Taking it to design does two things. First, the entities acquire everything analysis withheld: typed attributes, visibility marks, and operations; the computeReturn() that realises SR3.2 now appears, on Loan. Second, the solution-side classes the requirements never mention arrive: a «boundary» class for the desk screen the Librarian uses and a «control» class that runs the borrow use case. The Loan association class is promoted to an ordinary class holding one association to each of its former ends, the routine design move for association classes; note the multiplicities survive the promotion, so SR3.1 is still visible. This boundary/control/entity split keeps the UI, the use-case logic, and the data independent, and it is the seam the sequence diagram in Stage 9 sends its messages across.

Figure 12
Design class diagram for Borrow: boundary and control above, the entities in full below. Hover any class.
<<boundary>> BorrowScreen + scan(barcode: String) + showResult(msg: String) <<control>> BorrowController + borrow(barcode: String) - getCopy(barcode: String) uses <<entity>> LibraryMember + memberId: String + name: String - loanCount: int + countLoans(): int + borrow(c: BookCopy) <<entity>> Loan + startDate: Date + returnDate: Date + computeReturn(): Date <<entity>> BookCopy + barcode: String + status: LoanStatus + isAvailable(): bool + markOnLoan(): void 1 0..6 0..1 1
The same entities as Stage 5, now in full design notation: typed attributes with visibility (- loanCount is private), operations, and the promoted Loan holding an association to each former end of the borrows line. The multiplicities carry over, so a member still holds at most 0..6 loans (SR3.1) and computeReturn() realises SR3.2. Above the entities sit the two solution-side classes: the Librarian works the boundary (BorrowScreen), which forwards to the control (BorrowController), which drives the entities; dashed arrows are dependencies. The analysis fragment had none of this because operations, types, and boundary/control classes are solution decisions, not domain facts.

Stage 7: Activity diagram (the Borrow workflow)

The use-case description in Stage 4 is a numbered list; the activity diagram draws it as a flow, and makes the actor responsible for each step explicit through swimlanes. The lanes belong to the two actors, the BookBorrower and the Librarian; the system is deliberately not given a lane of its own (the caution section 7 raises), so the automated work surfaces inside the desk steps the Librarian drives. Both requirements branches are drawn: the damaged-barcode alternative (SR3.3) and the six-item limit (SR3.1).

Figure 13
Activity diagram for Borrow, across BookBorrower and Librarian lanes.
BookBorrower Librarian Present copy at the desk Scan copy barcode barcode readable? [readable] [unreadable] Enter barcode manually, log damaged barcode Check member's loan count loans < 6 ? [yes] Record loan and print slip (return date from book type) [no] Refuse loan and explain the limit Receive copy and slip
Two decisions carry the requirements: barcode readable? is SR3.3 (its manual-entry branch logs the damaged-barcode exception) and loans < 6 ? is SR3.1. Guards sit on the edges leaving each diamond, and the branches rejoin at merge nodes before the flow ends. There is deliberately no System lane: the lanes belong to the actors, and the automated work (looking up the copy, counting loans, computing the return date) happens inside the desk steps the Librarian drives. Compare figure 9b.3: naming only the participants keeps the diagram a model of the workflow rather than a sketch of the software.

Stage 8: Object diagram (a snapshot mid-borrow)

To check the class model of Stages 5 and 6 holds, populate it with one concrete case: member Adel borrowing copy BC-42, with the Loan that records it and the parent Book whose loan type sets the return date.

Figure 14
Object diagram: one member, one copy, one loan, and the copy's parent book.
adel : LibraryMember memberId = "M-1007" loanCount = 3 loan99 : Loan startDate = 14 Mar returnDate = 28 Mar copy42 : BookCopy barcode = "BC-42" status = OnLoan book7 : Book title = "Using UML" type = MediumLoan
Every value has a home and every link has a matching association from Stage 5: adel is linked through loan99 to copy42, whose status is now OnLoan and whose member's loanCount is 3 (under the limit). The parent book7 explains the one derived value: type = MediumLoan is why returnDate is 28 March, the start date plus two weeks, which is SR3.2 executed on real values. If any value had nowhere to sit, the class model would be wrong.

Stage 9: Sequence diagram (the messages, in order)

The activity diagram shows what happens; the sequence diagram shows who tells whom, in order, across the design classes of Stage 6. Time runs down; each lifeline carries an activation bar for exactly the period the object is doing work; the alt fragment carries the six-loan branch; and the Loan's lifeline begins at its «create» message, not at the top.

Figure 15
Sequence diagram for Borrow: activations, an alt fragment on the loan limit, and a created Loan.
: Librarian : BorrowScreen : BorrowController m : LibraryMember c : BookCopy 1: scan(barcode) 2: borrow(barcode) 3: getCopy(barcode) 4: countLoans() n loans alt [n < 6] 5: markOnLoan() copy OnLoan 6: «create» Loan(m, c, today) : Loan 7: computeReturn() returnDate loan recorded show due-date slip [else] refuse(limit reached) show refusal
The messages cross the boundary/control/entity seam from Stage 6: the Librarian drives BorrowScreen, which calls BorrowController, which asks the member (4), updates the copy (5), and creates the Loan (6). The shaded activation bars show when each object is busy: the screen and controller stay active for the whole use case, the entities only while they answer, and message 3 is a self-call (the controller looking up the copy). The Loan lifeline starts at its «create» message, its head box drawn at the creation height rather than at the top, and computeReturn() on the new Loan is SR3.2 executing. The alt fragment is the six-loan decision: one guarded branch runs, never both. Solid arrows are calls; dashed arrows are returns.

Stage 10: Communication diagram (same interaction, structural view)

The very same Borrow interaction, redrawn as links with Dewey-numbered messages. It confirms that every message rides on a link, an instance of an association that exists in the class model.

Figure 16
Communication diagram for Borrow (structural twin of Figure 15).
: Librarian : BorrowScreen : BorrowController m : LibraryMember c : BookCopy : Loan 1: scan(barcode) 1.1: borrow(barcode) 1.1.1: getCopy(barcode) 1.1.2: countLoans() 1.1.3 [n < 6]: markOnLoan() 1.1.4 [n < 6]: «create» Loan(m, c) 1.1.5 [n < 6]: computeReturn()
The Dewey numbers carry the nesting the sequence diagram showed by vertical position: scan is 1, the screen's forwarding call is 1.1, and everything the controller does while serving it is 1.1.1 to 1.1.5; the guards from the alt fragment reappear in square brackets on the guarded messages, and the small loop on the controller is the self-call. Each plain line is a link, an instance of an association in the class model; if a message had no link to ride on, the class model of Stage 5 would be missing a relationship. What this layout loses from Figure 15 is time; what it gains is structure.

Stage 11: State machine (the copy's lifecycle)

One entity in this thread has a state-dependent life worth its own diagram: the BookCopy. Borrowing is one transition in that lifecycle.

Figure 17
State machine for BookCopy: Borrow is the Available to OnLoan transition.
Available OnLoan Overdue borrow() return() after(due) return() Lost reportedLost reportedLost
The borrow() call that Stage 9 sent to the copy is the Available to OnLoan transition here. The diagram also answers questions the earlier stages did not: what happens when a loan runs past its date (after(due) to Overdue), how return() is legal from both OnLoan and Overdue, and how a copy leaves the lifecycle (reportedLost from either loaned state, then the final node; the fuller lifecycle in figure 8 attaches the fee to that path). State is the model that makes “which operations are legal now?” explicit.

Stage 12: Component and deployment (build-time and run-time structure)

The last two models leave behaviour behind and ask what the system is made of and where it runs. The Borrow logic lives in a Loans component that requires a persistence interface; at run time the desk client reaches a library server that holds the database.

Figure 18
Component view (left) and deployment view (right) for the library system.
component view Loans <<component>> Persistence <<component>> DataAccess deployment view Desk PC<<device>> <<artifact>> desk client Library Server<<device>> <<artifact>> loans.war <<artifact>> library.db <<HTTPS>>
Left, the component view: the Loans component requires the DataAccess interface that Persistence provides, drawn as the socket cupping the lollipop (an assembly connector). Right, the deployment view in the notation of figure 10: 3-D device nodes, each hosting its «artifact» boxes with the document icon; the Desk PC runs the desk client and reaches the Library Server over «HTTPS», and the server holds the deployed loans.war and the library.db file. Build-time parts on the left, run-time nodes on the right.

What this thread illustrates

One requirement, followed the whole way: from an interview to a use case and its description, an activity, a class model taken to design, a snapshot, the interaction as a sequence and a communication diagram, a state machine, and finally the component and deployment structure. Each model refines the previous and each surfaces questions the previous stage missed. The work of UML modelling is not drawing pretty ellipses; it is the disciplined re-asking, at progressively finer detail, of "what exactly does the system do?". A model that lets you skip the re-asking is not a useful model. A model that forces the re-asking, and lets the team write the answers down so they survive the project, is the artefact this chapter is teaching you to produce.

13.Pitfalls

Eight modelling pitfalls that show up in practice.

Drawn from Fowler's UML Distilled, recurring review findings on real UML models, and Brooks' general observations about modelling.

Use case as a noun

"Book borrowing" is not a use case label. Use cases are verb phrases: "Borrow a book". The label has to read as something an actor does.

Confusing <<include>> and <<extend>>

Include is unconditional and the base points to it. Extend is conditional and the extension points to the base. The arrows go opposite ways. Get the direction wrong and the meaning inverts.

Class diagram that mirrors the database schema

A class diagram is an abstraction of the domain; a schema is an artefact of the persistence layer. Drawing one for the other means the design decisions you should have made in the model were made for you by the database.

Class diagram with no methods

If every class has only attributes, you have drawn an entity-relationship diagram, not a class diagram. UML classes carry behaviour as well as data; if there is no behaviour, ask whether the class earns its place.

Sequence diagram that mirrors source code

A sequence diagram should capture the interaction at a level of abstraction worth discussing. If the diagram has one message per line of code, it is a code listing in a clumsy notation.

State machine for a stateless class

Drawing a state machine for a data holder, value object, or pure function adds notation without adding insight. State machines pay back when the class has states; otherwise they are over-engineering.

One huge use case diagram

A diagram with more than ten use cases stops being readable. Use composite use cases and split the diagram into a top-level overview with first-level expansions.

UML as a deliverable rather than a tool

Diagrams produced once, never looked at, never revised, are decoration. The team that benefits is the team that draws diagrams to think, refers to them in design conversations, and updates them when the design changes.

14.References

Sources cited above, and where to go next.

Sommerville's textbook and Prof Adel Taweel's lecture notes anchor this material; the works below are those directly referenced in the text, alongside the standard practitioner references.

Course material

Taweel, A. (2025/26). COMP433 Software Engineering: Unified Modelling Language (Chapter 4). Birzeit University lecture notes. The primary course source; the running examples (Library system, Mentcare), the diagram taxonomy, and the modelling conventions in this companion follow Adel's notes directly. Lecture decks: use cases & activity (1–89), class, object & sequence (90–156), component & deployment (180–223), UML intro (1–29).
Sommerville, I. (2015). Software Engineering (10th ed.). Pearson. Chapter 5 on System Modelling is the textbook treatment of the four model families (context, interaction, structural, behavioural) and the standard reference for the diagrams discussed here.

UML, primary references

Object Management Group (2017). OMG Unified Modeling Language (OMG UML), Version 2.5.1. The authoritative specification. Several hundred pages; the reference when notation questions are contested.
Fowler, M. (2003). UML Distilled: A Brief Guide to the Standard Object Modeling Language (3rd ed.). Addison-Wesley. The most-cited compact practitioner reference. Concise; opinionated; correct.
Booch, G., Rumbaugh, J. and Jacobson, I. (2005). The Unified Modeling Language User Guide (2nd ed.). Addison-Wesley. The "three amigos" book; the official user-level companion to the standard.

Originals that fed into UML

Booch, G. (1991). Object-Oriented Design with Applications. Benjamin/Cummings. The Booch method; the source of the class heuristics summarised in Section 8.
Rumbaugh, J., Blaha, M., Premerlani, W., Eddy, F. and Lorensen, W. (1991). Object-Oriented Modeling and Design. Prentice-Hall. The Object Modeling Technique; source of much of UML's class-diagram notation.
Jacobson, I. (1992). Object-Oriented Software Engineering: A Use Case Driven Approach. Addison-Wesley. The original published treatment of use cases.

Class and component design

Larman, C. (2004). Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd ed.). Prentice-Hall. The standard pedagogical reference for moving from use cases and a domain model to class and sequence diagrams.
Shlaer, S. and Mellor, S. (1992). Object Lifecycles: Modeling the World in States. Prentice-Hall. The source of the noun-verb analysis recipe summarised in Section 8.
Cockburn, A. (2001). Writing Effective Use Cases. Addison-Wesley. The reference for the use case description template used in Sections 5 and 6.

Adjacent course material

COMP433 Ch.3: Requirements engineering. The preceding chapter; use cases originate there and are deepened here. Read in sequence.