Domain Models & System Sequence Diagrams
Object-oriented analysis: describing the problem before designing a solution. You will learn to draw a domain model from a paragraph of text and a system sequence diagram from a scenario, the two questions that carried 25 marks in each past exam.
- You willturn a numbered passage into a correct domain class diagram, sentence by sentence.
- You willdecide confidently between attribute and class, subclass and enumeration, association and association class.
- You willdraw a system sequence diagram for one scenario, with the system as a black box.
- You willwrite an operation contract as before-and-after snapshots of domain objects.
Analysis and the Domain Model exam
Before you can design software, you have to understand the problem it solves. Object-oriented analysis (OOA) is that step: it investigates the problem and the requirements, and records what it finds in three artefacts. Design comes afterwards and creates a solution. A handy slogan is that analysis is about "doing the right thing", while design is about "doing the thing right".
| Artefact | Kind of model | Answers the question | UP home | Exam weight |
|---|---|---|---|---|
| Domain model (domain class diagram) | Static | What concepts exist in the domain, what do we need to remember about them, and how are they related? | Business Modeling discipline | high one 15-mark question in both past exams |
| System sequence diagram (SSD) | Dynamic | For one scenario, which events do the actors send to the system (a black box), in what order, and what comes back? | Use-Case Model | high one 10-mark question in both past exams |
| Operation contract | Pre/postconditions | What state changes in domain objects does one system operation cause? | Use-Case Model (optional) | low in the textbook (ch. 11); the slides show it only in the UP overview |
The three artefacts are not independent; each feeds the next. Everything starts from the use case text (Part I). The nouns in it suggest conceptual classes for the domain model, and the actor steps in it suggest the system events of the SSD. The diagram below traces the flow, following Larman's Figs. 9.1, 10.1 and 11.1.
The domain model supplies the vocabulary of the project: the class and attribute names that SSD parameters, contracts and the glossary all reuse. Later, in design, it also inspires the names of software classes in the domain layer. That keeps the representational gap low (the distance between how people think about the domain and how the code is written; see Part III). The SSDs identify the system operations, and each one becomes a message to a controller object when design starts (Part IV, Controller). The contracts then describe what each system operation does to domain objects.
Analysis investigates the problem and the requirements; design creates a conceptual solution. Domain models and SSDs belong to analysis, so they must contain no software decisions. Breaking this rule is the mistake markers penalise most often (§2.8).
What a domain model is
A domain model is a visual representation of conceptual classes or real-situation objects in a domain. The course puts it as "a representation of real-world conceptual classes in a non-technical manner".
In the Unified Process (UP) the term means real-situation conceptual classes, not software objects. A domain model is drawn as a UML class diagram with no operations, seen from a conceptual perspective, and it may show only three things: conceptual classes, the associations between them, and their attributes. Larman calls it a visual dictionary of the domain's noteworthy abstractions, vocabulary and information content. You could write the same information out as glossary text, but a picture shows the relationships far better.
In the UP the domain model is a specialisation of the Business Object Model that focuses on one domain, such as point-of-sale (POS). It is started and mostly finished during elaboration. It is also optional and partial: you model only the concepts that the current iteration's scenarios need, and spend a few hours at most. Aiming for a waterfall-style "complete and correct" model leads to analysis paralysis.
A model is useful if it captures the essential abstractions needed to understand the domain for the current requirements. That is why, in exams, a different but justified model still earns marks; the workshop solutions say so explicitly. Whenever you make a judgement call, write a one-line note saying why.
What a domain model is not
Because the model describes the real domain, anything that belongs to the software must stay out of it. This is the single most important rule of the topic, so here is the full list, with a typical mistake and the reason each is wrong.
| Not allowed | Example of the mistake | Why |
|---|---|---|
| Software artefacts | NOSQL DB Adapter, «interface», SalesDatabase, TransactionLogger, windows and UI | Not real-world concepts. The exception is when the domain itself is software, e.g. modelling GUIs. |
| Operations, methods, responsibilities | print(), makeStreamable(): boolean, delete(): void | Responsibilities are assigned during design (Part IV). |
| Visibility markers | + title, - name, # itemID | A software concept. If a tool forces markers, make them all the same. |
| Programming types | String, String[50], int, void, List<Episode> | Use no type, or a domain data type (Date, Money, Address). |
| Navigability arrows | Person ──pays for──▶ Item drawn with an arrowhead | Domain associations are bidirectional conceptual links. Only a reading-direction triangle is allowed. |
| Foreign-key or ID attributes that link classes | Cashier.currentRegisterNumber, Order.customerID | Relate classes with an association, not an attribute (§2.3). |
| Attributes typed by another concept | Cashier.currentRegister : Register | Use an association. |
customerID, the total is a derived attribute (/) with a domain data type, and the database has vanished because it is not part of the shop, it is part of the software.Don't drop a class just because it has no attributes, or because nothing about it seems to need storing. Classes without attributes, and classes with a purely behavioural role in the domain, are perfectly valid.
Check yourselfA classmate's domain model contains a class Episode with - title : String and + makeStreamable() : boolean, and a class NOSQL DB Adapter. List every problem.
Four problems. The - and + are visibility markers, which are a software concept. String and boolean are programming types; write just title. makeStreamable() is an operation, and responsibilities are only assigned in design. NOSQL DB Adapter is a software artefact, not a concept from the streaming domain, so it must go entirely.
Check yourselfWhy does an exam marker give credit to a domain model that differs from the model answer?
Because there is no single correct domain model. A model is judged on whether it captures the essential abstractions for the stated requirements. If your choice differs (say, a class where the answer has an attribute) and you justify it, typically with a short note, it still earns marks.
- Analysis produces the domain model, SSDs and (optionally) contracts; the first two carry 25 exam marks between them.
- A domain model is a visual dictionary: conceptual classes, attributes and associations, from the real world.
- No operations, visibility, programming types, arrowheads, foreign keys or software classes, ever.
Finding Conceptual Classes
The boxes of a domain model are conceptual classes, and the hardest part of the exam question is deciding which nouns deserve a box. This section gives you a precise idea of what a conceptual class is, then three techniques for finding them and a special kind, the description class, that beginners almost always miss.
Symbol, intension, extension exam · quotable
Informally, a conceptual class is an idea, thing or object in the domain. More formally, Larman describes a conceptual class by three aspects. They are worth learning word for word, shown here for Sale.
Three strategies for finding classes exam
Reuse or modify an existing model
The first, best and usually easiest option. Published analysis patterns already exist for common domains such as inventory, finance and health (Fowler's Analysis Patterns, Hay's Data Model Patterns).Use a category list
Walk through Larman's conceptual class category list (Table 9.1, below) and ask, for each category, "what in this domain fits here?"Noun phrase identification
Linguistic analysis: underline the nouns and noun phrases in the use cases or problem text, and treat each one as a candidate class or attribute.The category list is a checklist of the kinds of thing that usually turn out to be classes. For business systems, start with transactions, because they involve money and are therefore critical. The examples come from the POS, Monopoly and airline domains.
| Category | Examples |
|---|---|
| Business transactions start here | Sale, Payment, Reservation |
| Transaction line items | SalesLineItem |
| Product or service related to a transaction or line item | Item, Flight, Seat, Meal |
| Where the transaction is recorded important | Register, Ledger, FlightManifest |
| Roles of people or organisations; actors in the use case | Cashier, Customer, Store, Player, Passenger |
| Place of a transaction or service | Store, Airport, Plane |
| Noteworthy events, often with a time or place | Sale, Payment, MonopolyGame, Flight |
| Physical objects (especially for device control and simulations) | Item, Register, Board, Piece, Die, Airplane |
| Descriptions of things | ProductDescription, FlightDescription |
| Catalogs (descriptions are often kept in one) | ProductCatalog |
| Containers of things, physical or information | Store, Bin, Board, Airplane |
| Things in a container | Item, Square, Passenger |
| Other collaborating systems | CreditAuthorizationSystem, AirTrafficControl |
| Records of finance, work, contracts and legal matters | Receipt, Ledger, MaintenanceLog |
| Financial instruments | Cash, Check, LineOfCredit |
| Schedules, manuals and regularly referenced documents | DailyPriceChangeList, RepairSchedule |
Noun phrase identification is quick, but mapping nouns to classes is not mechanical, because natural language is ambiguous. The stepper below runs it on the POS Process Sale scenario and shows each of the pitfalls as it arises: synonyms, nouns that are only attributes, software terms, and implicit concepts that the category list has to supply.
- The input is the use case text. Nothing has been classified yet. Read it once, end to end, before marking anything.
- Underline every noun and noun phrase. Each is only a candidate for a class or an attribute; the hard part is the sorting that follows.
- Classes: the actors (Customer, Cashier), the business transaction (Sale, which the category list says to start with), its line item and the payment. None of these is "just a number or text", so each gets a box.
- Attributes: "item identifier", "price" and "item description" are plain values, so they are attributes of some class rather than classes. "Running total" and "total with taxes" are the same thing, computed from other data, so they become one derived attribute
/total. - Synonyms and software terms. Different words can name one concept: "goods and/or services" become
Itemand "POS checkout" becomesRegister; choose one name. "System" names the software under design, so it is excluded. - Implicit concepts from the category list. Some concepts are never written as nouns at all. "Descriptions of things" suggests
ProductDescription(the home of description and price), "catalogs" suggestsProductCatalog, and "place of transaction" suggestsStore. This is why Larman recommends combining noun phrases with the category list.
- Synonyms: different words for the same concept ("goods and/or services" and Item). Pick one name.
- Attributes: some nouns are only values (price, date, name, quantity).
- Out of scope: some nouns are irrelevant in this iteration ("Accounting", "commissions").
- Implicit concepts: important concepts such as a line item or a transaction may never appear as nouns; the category list catches them.
- Software terms: "database", "screen", "button" describe the software and are excluded.
Naming and scope guidelines
A map uses the names people actually use for places, leaves out irrelevant features, and never adds things that are not in the territory. So use the domain's own words: a library has a Borrower or Patron, not a Customer. Leave out what is out of scope, and don't invent things the text doesn't mention.
A report usually duplicates information already in the model, so leave it out unless it has its own business role. A receipt entitles the holder to return goods, so include it in the iteration that handles returns. The LMS workshop solution includes a Receipt because its use case requires one to be emailed.
In abstract domains such as telecoms, listen to the experts' core vocabulary. It gives concepts like Message, Connection, Port, Route and Protocol, even though you cannot touch them.
Let the model grow. It is normal to discover missed concepts later, so draw boxes you can extend rather than polishing early.
Check yourselfA library text says: "Patrons borrow books. The system stores each loan in a database and shows the due date on screen." Which nouns become classes, and which do you drop?
Classes: Patron (keep the library's own word: mapmaker), Book, and Loan (a noteworthy event with a time). Attribute: the due date belongs to Loan (and can be derived from the start date and loan duration, as in §2.6). Drop: "system", "database" and "screen" are software terms.
Description classes
Here is a trap the noun list will not warn you about. A description class holds information that describes something else, independently of whether any instances of that thing currently exist. Larman calls this the Item-Descriptor pattern. Its job is to stop information vanishing when the things it describes are deleted.
- information about an item or service is needed independent of whether any instances currently exist;
- deleting instances of the described thing would lose information that must be kept;
- it reduces redundant or duplicated information.
The same split turns up everywhere once you look for it. A FlightDescription holds the route and flight number, while a Flight is one specific date and time; the routes still exist even if every flight is cancelled. A mobile plan description (the "gold package") is separate from a package that has actually been sold. And in the course's Tony's Pizza case study, a PizzaStyleDescription holds the style name, the prices per size and the standard toppings, whereas a Pizza is an actual pizza added to an order, which the customer may customise with extra toppings.
PizzaStyleDescription is the description class (one "Margherita" style) and Pizza the described thing (the Margherita in tonight's order). Notice the two different associations to Topping: a style is made of its standard toppings, while a pizza may add up to five more.The case-study video explains each modelling decision, and every one of them is a rule you will meet again in this Part:
- orderNumber is an attribute because it is just a number or string.
- /totalPrice and Pizza /price are derived: a pizza's price comes from its style's price for the chosen size, plus any added toppings.
- Order–Pizza is 0..* because an order may contain only drinks.
- Pizza–Topping is 0..5 because the requirements allow "up to five additional toppings".
- Style is a class, not an attribute. A style has its own attributes (prices) and associations (toppings), so it is too rich to be text.
- deliveryFee [0..1] is an optional attribute, because pickup orders have no delivery fee.
Check yourselfAn airline keeps flight number QF1 (Sydney to London) on its timetable, and also tracks the QF1 that departs on 3 March. Draw the two classes and the association.
FlightDescription {number, plus the route} 1 —Describes— * Flight {date, time}. The route and number belong to the description because they exist even if every QF1 flight is cancelled; the date and time belong to the individual flight. This is the same split as ProductDescription/Item.
Check yourselfWhy is a pizza's style modelled as a class in Tony's Pizza rather than a pizzaStyle : text attribute?
Because of the richness test: the style has attributes of its own (prices per size) and associations of its own (its standard toppings). Anything with its own attributes or associations is too rich to be an attribute and must be a class. pizzaStyle : text is listed among the mistakes markers penalise.
- A conceptual class has a symbol (its name), an intension (its definition) and an extension (its instances).
- Find classes by reusing models, by the category list (start with transactions) and by noun phrases, watching for synonyms, attributes, software terms and implicit concepts.
- Use the domain's own words (mapmaker), and add a description class when information must outlive the things it describes.
Attributes
Once you have the boxes, you need to decide what goes inside them. Attributes record the plain values the domain needs to remember. Most of the marks in this area are lost through one confusion, between something that is a value and something that is a thing, so that is where this section spends its time.
An attribute is a logical data value of an object. Show one when the requirements suggest or imply a need to remember the information.
For example, a POS receipt shows the date and time and the store's name and address, so the model needs Sale.dateTime, Store.name and Store.address. If nothing in the requirements needs a value, leave it out.
Notation
Attributes go in the second compartment of the class box. The full UML syntax is visibility name : type multiplicity = default {property}, but a domain model uses only a small part of it. There are no visibility markers: Larman assumes attributes are private and doesn't draw them, and the course says to remove them.
name, name : DataType, /derived and name [0..1] (the guide also writes the optional form middleName : [0..1]), plus enumerations written in braces. Derived attributes are covered in §2.6.Attribute or class? The most common mistake exam
If we do not think of some conceptual class X as a number or text in the real world, X is probably a conceptual class, not an attribute.
Larman's two examples show the guideline at work. Should a sale have an attribute store, or should Store be a class? A store is a legal entity that occupies space, not a piece of text, so it is a class. In the same way, rather than writing Flight.destination, make Airport a class and associate them with Flight Flies-to Airport, because an airport is a huge physical thing.
Store.The converse also holds. If a noun really is just a number or a string with no structure of its own, keep it as an attribute: in Tony's Pizza, an order number and an address string are examples. And Tony's Pizza supplies a second test, the richness test: if the noun has its own attributes or associations, as a pizza style has prices and toppings, it must be a class.
Check yourselfAttribute or class? (a) a student's year level; (b) the school a student attends; (c) a car's paint colour; (d) the pizza style of a pizza.
(a) Attribute: a number. (b) Class, in the guide's tutoring answer: a school is an organisation, not text (the Store/Airport rule). A plain school attribute is also defensible if nothing else about schools is needed, and the official answer uses one, so state your assumption. (c) Attribute: colour is a data type. (d) Class: a style has its own prices and toppings, so it fails the richness test for an attribute.
Data types only; relate concepts with associations
Attribute types should be data types: Boolean, Date/DateTime, Number, Character, String/Text, Time, Address, Colour, PhoneNumber, ZIP/postcode, UPC/SKU, and enumerations such as size : {small, large}. What makes something a data type is that its unique identity is not meaningful: values are compared by value, not by identity. Data-type values are also usually immutable.
It follows that you should relate conceptual classes with an association, not an attribute. In particular, use no attributes that represent foreign keys exam. Attributes such as currentRegisterNumber, customerID and carID are relational-database habits. How a relationship is implemented (a foreign key, a pointer, …) is a design decision, which Larman defers to avoid "design creep". The same goes for an attribute typed by another concept, such as Cashier.currentRegister : Register.
number is fine, because it identifies the register itself. What is wrong is copying that number into another class to link them. The rule applies to the conceptual model only; in the design model (Part III) software attributes can have any type.When a "number or string" deserves its own data-type class
Some values look primitive but have structure. Larman's Table 9.3 says to model such a value as a new data-type class if it:
| Make a data-type class if it… | Example |
|---|---|
| is composed of separate sections | a phone number, a person's name |
| has operations such as parsing or validation | a social security number |
| has other attributes | a promotional price with start and end dates |
| is a quantity with a unit | money in a currency, weight in kg |
| abstracts several types | ItemID generalises UPC and EAN |
You can show such a type either inside the attribute compartment (itemID : ItemID) or as its own box joined by an association. Both are fine, so choose based on what you want to emphasise. Quantities and units deserve special care: "price = 13" is meaningless without a unit, so write amount : Money (Money is a Quantity whose unit is a currency), or model a Quantity —Is-in— Unit structure.
If a class can have many values of the same kind of attribute at the same time, don't put that attribute in the class; put it in another class associated with it. A Person with several phone numbers gets an associated PhoneNumber class rather than phone1, phone2. A Store that has a different merchantID for each authorisation service is the same problem, and it leads to association classes (§2.6).
Check yourselfSpot the errors: Order { orderID : int, customerID, total : 13 }.
int is a programming type (drop it, or use a domain type). customerID is a foreign key: replace it with an association Customer 1 — * Order with a verb-phrase name. total : 13 has no unit; a total is a quantity, so write total : Money, and since it can be computed from the order's contents it should be /total. orderID itself is acceptable, because it identifies the order itself (like employeeID in the car saleroom answer), not another class.
- An attribute is a remembered data value:
name,name : DataType,/derived,[0..1]optional,{a, b}enumeration; no visibility. - Not a number or text in the real world, or has its own attributes or associations? Then it is a class.
- Relate classes with associations, never with foreign-key IDs or class-typed attributes.
Associations
Classes on their own are a list of words; associations turn them into a picture of how the domain hangs together. The skill is choosing which relationships to draw, then labelling each one fully: a name, a reading direction when needed, and a multiplicity at both ends.
An association is a relationship between classes (more precisely, their instances) that indicates some meaningful and interesting connection.
When to show an association exam
Include two kinds. First, "need-to-remember" associations: relationships whose knowledge must be kept for some time, anywhere from milliseconds to years. A Sale must remember its SalesLineItems, or you could not reconstruct the sale or print a receipt; a Piece must remember which Square it is on. Second, associations suggested by the Common Associations List below.
Leave out transient facts. "The dice total indicates the square to move to" and "a cashier looked up a product description" are both true, but neither needs remembering afterwards. And be parsimonious: n classes can have n(n−1)/2 associations, so 20 classes could have 190 lines, and too many lines become visual noise.
An association is not a data flow, a foreign key, an instance variable or a software link. It is a statement that the relationship is meaningful in the real domain. Many associations will later be implemented as navigation paths, but that decision belongs to design.
| Relationship | Examples |
|---|---|
| A is a transaction related to another transaction B | CashPayment–Sale, Cancellation–Reservation |
| A is a line item of transaction B | SalesLineItem–Sale |
| A is a product or service for transaction (or line item) B | Item–SalesLineItem, Flight–Reservation |
| A is a role related to transaction B | Customer–Payment, Passenger–Ticket |
| A is a physical or logical part of B | Drawer–Register, Square–Board, Seat–Airplane |
| A is physically or logically contained in or on B | Register–Store, Item–Shelf, Passenger–Airplane |
| A is a description for B | ProductDescription–Item, FlightDescription–Flight |
| A is known, logged, recorded, reported or captured in B | Sale–Register, Piece–Square, Reservation–FlightManifest |
| A is a member of B | Cashier–Store, Player–MonopolyGame, Pilot–Airline |
| A is an organisational subunit of B | Department–Store, Maintenance–Airline |
| A uses or manages or owns B | Cashier–Register, Player–Piece, Pilot–Airplane |
| A is next to B | SalesLineItem–SalesLineItem, Square–Square, City–City |
Notation and naming exam
Records-current and RecordsCurrent are legal. Without a ▸ or ◂, the convention is to read left-to-right or top-to-bottom.The line is plain. An association is inherently bidirectional: you can logically traverse it from either end, so you never put navigability arrowheads on domain associations. The name is capitalised, sits near the middle of the line, and follows the format ClassName-VerbPhrase-ClassName, so it must read as a meaningful sentence: "Sale Paid-by CashPayment", "Player Is-on Square". The reading-direction arrow ▸ or ◂ is a small filled triangle beside the name; it says nothing about navigation or visibility and is optional.
The official 2021 S2 answer carries a note that says it outright: "The associations need to be named. They cannot be anonymous." The course's own notation reference (University Club) uses the weak names "Has" and "Uses"; in an exam prefer specific phrases such as "Holds" and "Manages-funds-in".
Exceptions. For composition the name is implicitly "Has-part", so it may be omitted (§2.6). Larman also omits names when the meaning is obvious and a name would only add clutter, but in exams you should name them.
Multiplicity exam
Multiplicity defines how many instances of class A can be associated with one instance of class B, at a particular moment (not over time). To read it, look at the number written next to class B: it answers "for one A, how many Bs?"
Store 1 —Stocks— * Item: one store stocks many (zero or more) items, and each item is stocked in exactly one store. The instance picture on the right is what the class diagram allows at any single moment.The words "at a particular moment" matter. A used car can be resold many times over its life, but at any moment it is Stocked-by one dealer. Likewise Married-to is 0..1 in a monogamous jurisdiction, even though a person may marry several times in sequence.
| Expression | Meaning | Expression | Meaning |
|---|---|---|---|
* (= 0..*) | zero or more, "many" | 1..40 | one to forty |
1..* | one or more | 5 | exactly five |
1 | exactly one | 3, 5, 8 | exactly 3, 5 or 8 |
0..1 | zero or one (optional) | 0..4, 1..4 | bounded ranges: "at least one but no more than four subjects" is 1..4 |
Multiplicity records a domain constraint you care about checking, so whether an end is 1 or 0..1 depends on context. Physically, a sold item is no longer stocked, which suggests 0..1 at the Store end; but if every Item record in the system must belong to a store, choose 1. Whether a Person Works-for one or many Companies depends on whether the model is for a tax office (many) or a union (one). In exams, choose the value the text implies, and add a short note when you make an assumption.
Check yourselfTranslate into multiplicities: "A club member is enrolled in at least one but no more than four subjects; a subject has any number of members."
Member * —Enrolled-in— 1..4 Subject. The 1..4 goes next to Subject, because it answers "for one Member, how many Subjects?", and the * goes next to Member. This is exactly the course's University Club notation example.
Several associations between the same two classes
Two classes can have several distinct relationships. Each is a separate, separately named line; never merge them into one line with two names.
Customer–Car is linked by both Purchases and Has-as-favourite.Roles and role names
Each end of an association is a role, which can have a name, a multiplicity and (in design only) navigability. A role name is a lowercase word at the line end describing the part the object plays: Flight * —Flies-to— 1 City can carry the role name destination at the City end. Use one only when the role is unclear; if you omit it, the default is the class name in lower case. In a design class diagram role names become attribute names (Part III).
There are two ways to model human roles, each with its own advantage, shown side by side below.
Check yourselfA student draws Person ──pays for──▶ Item. Name two separate problems.
(1) The arrowhead is a navigability arrow, a design notation; domain associations are plain lines (a small ▸ beside the name is the only arrow allowed). (2) It skips the intermediate concepts: a person pays for items through a transaction (Sale/Payment) made up of line items, which the category list says to model first. This exact example is on the Workshop 11 revision slide. Also check the name is capitalised with multiplicities at both ends.
- Draw an association only if the link must be remembered; be parsimonious.
- Plain line, Capitalised-Verb-Phrase name, optional ▸, multiplicity at both ends; read the number next to the far class.
- Distinct relationships get distinct lines; role names go at the ends when the role is unclear.
Generalisation and Specialisation exam
Many domains contain "kinds of" things: kinds of payment, kinds of staff, kinds of person. Generalisation lets you say what they have in common once, on a superclass, and what is special about each kind on its subclasses. Both past exams opened with exactly this: "for all persons … for students we also … there are two kinds of staff".
Generalisation is the activity of identifying commonality among concepts and defining superclass (general concept) and subclass (specialised concept) relationships. It builds a taxonomy.
Its benefits are economy of expression, less repeated information and better comprehension; later it also leads to software inheritance hierarchies that reduce duplicated code. But remember that these are conceptual classes: "inheritance" is a software mechanism and plays no part in domain modelling, and the conceptual hierarchy may or may not be mirrored in the design.
The relationship has two equivalent definitions. By intension, a superclass definition is more general (more encompassing) than a subclass definition. By extension, thinking of classes as sets, all members of a subclass set are members of the superclass set.
The 100% rule and the Is-a rule exam · quotable
The whole superclass definition must apply to the subclass. The subclass conforms to 100% of the superclass's attributes and associations.
All the members of a subclass set must be members of their superclass set. Test it with the sentence "Subclass is a Superclass": "CreditPayment is a Payment".
A correct subclass must satisfy both rules. In practice that means an attribute or association that applies to every subclass is placed once, on the superclass, while one that applies to only some subclasses must go down to those subclasses. If only tutoring staff tutor, the Tutors association must attach to TutoringStaff, not Staff.
CommitteeMember 1 —Creates— * Event.When to create a subclass exam
A correct partition is not automatically a useful one. Larman's example is Customer split into MaleCustomer and FemaleCustomer: legal, but useless for a POS system. So you also need a motivation.
- it has additional attributes of interest (a library
BookhasISBNandauthors; aVideohasduration); - it has additional associations of interest (
CreditPayment —Identifies-credit-with— CreditCard,Video —Directed-by— Director); - it is operated on, handled, reacted to or manipulated differently, in ways of interest (a CreditPayment is authorised differently; library
Softwarerequires a deposit); - it represents an animate thing (animal, robot) that behaves differently, in ways of interest (market research into the shopping habits of different groups).
The lecture slide lists criteria 1–3; Larman adds 4.
The flip side is when to create a superclass: when the potential subclasses are variations of a similar concept, they conform to the 100% and Is-a rules, and they share an attribute or an association that can be factored out. CashPayment, CreditPayment and CheckPayment all have an amount and all Pay-for a Sale, so a superclass Payment holds both.
amount) and shared association (Pays-for) sit once on the superclass; each subclass with its own association (CreditCard, Check) has a reason to exist. CashPayment has no extra features here, but it completes the partition and is handled differently.The counter-example: kinds that differ only by a value
The lecture's library text says "Students, staff and guests … the only difference is a different borrowing limit." These user kinds have no extra attributes, no extra associations and no different handling; only the value of the limit differs. So do not subclass.
transmission : {automatic, manual} rather than AutomaticCar and ManualCar subclasses (§2.7).If subclasses would differ only in the value of an attribute, use an attribute (often an enumeration), not subclasses.
Don't over-generalise either. Larman's authorisation-transaction example shows that ever-finer levels of subclassing add complexity without improving understanding, so stop at the level that adds value.
Abstract conceptual classes exam
If every member of class C must also be a member of a subclass, then C is an abstract conceptual class.
So if a Payment could exist that is none of Cash, Credit or Check, Payment is not abstract. Mark an abstract class by writing its name in italics or adding {abstract}; in handwritten exams write {abstract}, because italics are hard to see. It is worth showing because it constrains which classes can have direct instances, which clarifies the domain rules.
The lecture slide's guidelines say "(a) declare superclasses abstract" and "(b) append the superclass name to the subclass" (CashPayment, CreditPayment). On (a), Larman's actual rule is the definition above: abstract only when the partition is complete. In typical exam texts ("there are two kinds of staff…", "for all persons we need…") the partition usually is complete, so the result is the same. Guideline (b) is a naming convention; apply it where it is natural (TutoringStaff, AdminStaff).
Don't model changing states as subclasses
An object moves between states over its life, but it can never change its class. So states such as "unauthorised" and "authorised" must not become subclasses. Instead, associate the concept with a state hierarchy, or leave states out of the domain model and show them in a state machine (Part V).
zone_state : {active, inactive}, as in the Workshop 11 model.Check yourselfA car saleroom text says "a car has transmission type (either automatic or manual)". Subclasses or attribute?
An enumeration attribute, transmission : {automatic, manual}. AutomaticCar and ManualCar would have no extra attributes, associations or handling, so none of the "when to subclass" criteria holds. This is what the official answer does, though it adds a note that subtypes would also be possible, so markers accept them as an alternative.
Check yourself"For all persons we need their name. For students we also need their year level. For staff we also need when they joined." Should Person be abstract?
Yes, if every person of interest is either a student or a staff member: then every member of Person is also a member of a subclass, which is the definition of abstract. Write {abstract} under the name. (The official 2021 S1 answer didn't mark it, so it is correct but optional.)
Check yourselfWhich two rules must every correct subclass satisfy, and what is the quick test for the second?
The 100% rule (the whole superclass definition, all its attributes and associations, applies to the subclass) and the Is-a rule (every member of the subclass set is a member of the superclass set). Test the Is-a rule by saying "Subclass is a Superclass" aloud.
- Hollow triangle at the superclass; shared attributes and associations go up, partial ones go down.
- Subclass only with a motivation: extra attributes, extra associations, different handling, or different behaviour of an animate thing.
- Differing only by value → enumeration attribute. Changing states → not subclasses. Complete partition →
{abstract}.
Association Classes, Composition and Other Refinements
Sometimes a plain line cannot say enough. A piece of data may belong to the link between two things rather than to either thing, or a link may be a strong whole–part bond. This section covers those two refinements, then the smaller ones from Larman ch. 31: derived elements, time intervals, qualifiers, reflexive associations and packages.
The problem association classes solve
Authorisation services assign each store a merchant ID, and a store has a different merchantID for each service. Where does merchantID live? Not in Store, because a store has many values. Not in AuthorizationService either, because a service has one per store. The value really belongs to the pair (Store, AuthorizationService), that is, to the association itself.
An association class lets you attach attributes (and associations) to an association. It is a normal class box joined by a dashed line to the association line.
Larman gives three clues that you need one: an attribute is related to an association rather than to either class; instances of the class have a lifetime dependency on the association; or there is a many-to-many association with information about the association itself. That last one is the classic clue: whenever you see a many-to-many line, look for a lurking association class.
CommitteeMember 1 —Has— * Position with Appointment {date_of_commencement} (see the appendix).An association class has exactly one instance per pair of linked objects. If the same pair can be related many times (a tutor tutors the same student in many sessions; a customer hires the same car on many dates), an association class is not enough. Instead, reify the relationship as a full class, such as TutoringSession or Rental, with ordinary associations to both sides. The tutoring answer in §2.7 uses both techniques.
Check yourselfA university records, for each student in each subject, the final mark. A student takes many subjects and a subject has many students; each student takes each subject once. Model the mark.
Student * —Enrolled-in— * Subject with an association class Enrolment {finalMark}. The mark belongs to the pair, not to the student (who has many marks) or the subject (which has many). Because each pair occurs once, an association class is valid. If students could repeat a subject, you would reify Enrolment as an ordinary class instead.
Aggregation versus composition
UML has two kinds of whole–part relationship. Aggregation (shared aggregation) is a vague "whole–part" link to which UML gives no meaning distinct from a plain association; Rumbaugh calls it a "modeling placebo". Composition (composite aggregation) is a strong whole–part relationship with three rules:
- A part belongs to only one composite at a time.
- The part must always belong to a composite: there are no free-floating fingers.
- The composite is responsible for creating and deleting its parts; if it is destroyed, its parts are destroyed or moved to another composite.
| Aggregation (shared) | Composition (composite aggregation) | |
|---|---|---|
| Notation | hollow diamond ◇ at the "whole" end | filled diamond ◆ at the whole (composite) end |
| Semantics | vague whole–part, no meaning beyond a plain association | strong whole–part, with the three rules above |
| Larman's advice | Don't use it; use composition where appropriate, otherwise a plain association | show it when it clearly applies; "If in doubt, leave it out." |
| Multiplicity at the whole end | any | 1 (or 0..1) |
| Name | needed | usually omitted (implicitly "Has-part") |
Show composition when the part's lifetime is bound within the composite's (a create–delete dependency), there is an obvious physical or logical whole–part assembly, some properties propagate from composite to parts (such as location), or operations propagate (destruction, movement, recording). The benefit is clarity about whether a part can exist on its own; in design it also identifies the Creator, since the composite creates its parts (Part IV), and it signals cascading deletes and copies. Still, leaving composition out of a domain model is not a serious error, and debating aggregation wastes exam time.
Derived elements
A derived attribute or association can be computed from other information. It is marked with a / prefix, as in /total or /quantity.
Avoid showing derived elements, since they add complexity without new information. Add one when it is prominent in the domain terminology and leaving it out would impair comprehension.
For example, Sale /total is derived from the line items and product prices, and SalesLineItem /quantity can be derived from the number of associated Items. Tony's Order /totalPrice and Pizza /price are derived. In the tutoring exam question, "the number of tutoring sessions they have been involved in" becomes Student /numberOfSessions, derived from the count of linked sessions. When the exam text explicitly asks for such a quantity, show it, with the slash.
Time intervals
Information is often valid only for a period. Larman uses this to fix an iteration-1 error: if a SalesLineItem used the current price in ProductDescription, changing the price would rewrite old sales. One fix is to copy the price into the line item at the time of sale. A more robust fix keeps a price history, shown on the left below. The library example from the lecture, on the right, has the same flavour: a Loan between User and Item with start and finish dates (or a returned? flag). Because the library tracks the complete history of loans, and the same user can borrow the same item many times, a Loan must be a class. Its due date can be derived from the start and the loan duration.
ProductPrice with an active interval keeps old and future prices; a Loan class keeps every borrowing. The note shows a constraint in braces: plain natural language is fine.Qualified and reflexive associations
A qualifier is a small box attached to the class at one end of an association, holding an attribute such as itemID. It selects objects at the far end by that value, which usually reduces the far multiplicity from many to one. In a domain model it communicates how things are distinguished in the domain, not a design decision about lookup keys, so use it sparingly: it easily slides into "design-think". A reflexive association links a class to itself, and role names are essentially required, because otherwise the two ends cannot be told apart.
1..* to 1. Right: a reflexive association with role names (blue) at both ends; without them you could not tell which end is the parent.Packages
Large domain models can be split into UML packages (tabbed folders) such as Domain::Core, Payments, Products and Sales. A class shown in a package that does not own it is written Package::Class. Group elements that share a subject area, sit in the same class hierarchy, take part in the same use cases, or are strongly associated. This is rarely examined for domain models; package diagrams are covered in Part VIII.
Domain-model notation cheat-sheet exam
| Element | Domain-model notation | Notes |
|---|---|---|
| Conceptual class | Box with a singular, capitalised domain noun; attribute compartment; no operations compartment | Attribute-less classes are fine |
| Attribute | name or name : DataType; name : [0..1] optional; /name derived; enumeration kind : {a, b} | No visibility, no programming types |
| Association | Plain line + Capitalised-Verb-Phrase name + optional ▸ + multiplicity at both ends | No arrowheads |
| Role name | Lowercase word at a line end | Needed on reflexive associations |
| Generalisation | Hollow triangle pointing to the superclass | Check the 100% and Is-a rules |
| Abstract class | Italic name or {abstract} | Every instance belongs to some subclass |
| Association class | Class box + dashed line to the association line | For data about the link |
| Composition | Filled diamond at the whole end | "If in doubt, leave it out"; avoid hollow-diamond aggregation |
| Qualifier | Small box on the near class holding the key, e.g. [itemID] | Reduces the far multiplicity |
| Constraint | {text} in braces, e.g. { Number of unreturned loans ≤ borrowLimit } | Natural language is fine |
| Note | Dog-eared rectangle with a dashed connector | For assumptions, e.g. "One member only for each [President, Treasurer]" |
Finally, how does a domain model differ from a design class diagram (DCD, Part III)? A DCD adds operations, navigability arrows, visibility, software types and software-only classes (controllers, adapters, interfaces), and it may restructure associations into attributes. The appendix draws one of each side by side.
Check yourselfComposition or not? (a) Board and Square in Monopoly; (b) Library and Book; (c) Order and OrderLine.
(a) Yes: each square is part of exactly one board and is created and destroyed with it (Larman's Board 1 ◆— 40 Square). (b) Doubtful: books can be transferred to another library or withdrawn without the library ending, so a plain association is safer ("if in doubt, leave it out"). (c) Yes: transaction line items are parts of their transaction, like Sale 1 ◆— 1..* SalesLineItem.
Check yourselfAn exam text says "we need to know the number of orders each customer has placed". How do you show it?
As a derived attribute Customer /numberOfOrders, alongside the association Customer 1 —Places— * Order it is computed from. The text asks for the quantity explicitly, so show it with the slash rather than leaving it implicit.
- Data about a link → association class (dashed line to the association); if the same pair can repeat → a full event class.
- Composition ◆ at the whole for exclusive, created-and-deleted parts; avoid aggregation ◇.
/derivedonly when the domain talks about it; qualifiers reduce the far multiplicity; reflexive associations need role names.
The Exam Method: Numbered Sentences → Domain Class Diagram exam · 15 marks
Everything so far comes together in one exam question. You get a short passage with numbered sentences and the instruction: "The passage below describes a … domain. The sentence numbering is provided … Draw a domain class diagram modelling the elements of the description." It is worth 15 marks in both past papers. The project rubric's tip applies directly: each class and relationship should map to an element of the problem description. So the method works sentence by sentence and finishes by ticking off every sentence number.
The eight steps
- Read every sentence and annotate it. Nouns are candidate classes or attributes; verb phrases linking two nouns are candidate associations. "Kinds of", "types of" or "for all X … for Y also" signal generalisation. "For each [pairing] we need …" points to an attribute of a relationship, an association class. "The number of …" or "total …" signals a derived attribute, and "either A or B" an enumeration.
- Classify each noun as class or attribute, using the number-or-text rule and the richness test. Merge synonyms; drop out-of-scope and software nouns. Give each class a singular name in the domain's own vocabulary.
- Build the hierarchies. Put common attributes on the superclass. Check each subclass passes the 100% and Is-a rules and has at least one "when to subclass" motivation; if kinds differ only by a value, use an attribute or enumeration. Mark a superclass abstract if every instance must be one of the subclasses.
- Place each attribute on the most general class it applies to 100%. Never repeat an inherited attribute in a subclass. Data types only; no IDs that link to other classes.
- Add associations for each relationship phrase, attached at the most specific class that 100% participates (
TutoringStaff, notStaff). Name each with a verb phrase, add a reading direction if the layout is ambiguous, and put multiplicity at both ends, derived from words like "one", "any number", "at least one", "up to five", "more than one". Where the text is silent, choose a reasonable value and note the assumption. - Find information that belongs to a relationship. If each pair is linked at most once, use an association class; if the same pair can repeat, or more than two parties are involved, use a reified event/transaction class.
- Add derived attributes, marked
/, wherever the text asks for a computable quantity. - Check against every sentence and clean up. Tick off each sentence number. Remove all design notation (operations, visibility, arrows, String/int, foreign keys), and add a note for each assumption.
Worked example A: 2021 S1 Q4, the tutoring domain
The passage, with its sentence numbering:
1. For all persons of interest in the domain, we need to know their name, address, phone number, and date of birth. 2. For students we also need to know their year level, school, and the number of tutoring sessions they have been involved in (see below). 3. For staff we also need to know when they joined our organisation. 4. There are two kinds of staff: Tutoring staff and Admin staff. 5. Tutoring staff members tutor students: we need to track which staff members were involved in tutoring a student and, for each, whether they were a senior or junior tutor. 6. Each time students are tutored by staff members (students may be tutored by more than one tutor at a time, e.g. senior plus junior in training, or second tutor for a large class), we need the date/time, and activity type for that session.
Step through the stepper below. The banner shows the sentence being modelled; the gold outline marks what that sentence added. Sentence 5 is dealt with after sentence 6, because the association class it calls for sits on the session association that sentence 6 creates.
- Start with an empty page and the six sentences. Read them all before drawing, so you know that "persons" will split into students and staff, and that sessions arrive in sentence 6.
- Sentence 1 →
Person. "For all persons … name, address, phone number, date of birth" lists attributes common to everyone, so by the 100% rule they go on a superclass. Every person of interest turns out to be a student or staff member, so the partition is complete and Person is{abstract}. Dates use theDatedata type. - Sentence 2 →
Student. "For students we also…" signals a subclass with extra attributes:yearLevel. "The number of tutoring sessions" is computable from the student's linked sessions, so it is the derived attribute/numberOfSessions. Draw the hollow triangle at Person. - Sentence 2, again: the school. A school is an organisation, not text (Larman's Store/Airport rule), so
Student * —Attends— 1 School. The ◂ says to read from Student towards School. A plainschoolattribute is defensible if nothing else about schools is needed (the official answer does that); state your assumption either way. - Sentence 3 →
Staff. "For staff we also … when they joined" is another subclass with an extra attribute,dateJoined : Date. It shares Person's triangle. - Sentence 4 →
TutoringStaffandAdminStaff. "Two kinds of staff" is generalisation. TutoringStaff has an extra association (it tutors), a "when to subclass" motivation; AdminStaff completes the stated partition. The partition is complete, so Staff becomes{abstract}too. Tutoring must not go on Staff, or AdminStaff would break the 100% rule. - Sentence 6 →
TutoringSession. "Each time … we need the date/time and activity type for that session": a session is a noteworthy event with its own data. It recurs for the same student and tutor, so it must be a class, not an association class on Student–Tutor (one instance per pair). Multiplicities: "more than one tutor at a time" and "a large class" give 1..* tutors and students per session; a student or tutor may have any number of sessions, 0..*. - Sentence 5 → association class
TutorParticipation. "Which staff members were involved and, for each, whether senior or junior": the role belongs to one tutor's participation in one session. Not the tutor (junior in one session, senior in another), not the session (several tutors with different roles). Many-to-many with data about the link is the textbook clue, and each (tutor, session) pair occurs once, so an association class is valid. - Check every sentence and add notes. All six are covered. Notes record the derived attribute's meaning and the abstract assumption. Nothing from design remains: no operations, visibility, programming types, arrowheads or ID attributes.
- Reified participation:
TutoringStaff 1 — * TutorParticipation * — 1 TutoringSessionas an ordinary class. Semantically equivalent. - Two named associations,
Senior-tutor-inandJunior-tutor-in(multiple associations, §2.4); less flexible if more roles are added. - An attribute on the tutor,
Experience : {junior, senior}. This is the official answer: it reads sentence 5 as the tutor's grade. (The guide's first version wrongly listed this as a choice to avoid.) The association class remains the more precise reading of "for each".
- Subclasses like
Student → JuniorStudentorSeniorTutor/JuniorTutor: seniority is a value, not a kind with its own attributes or associations. - Putting
TutorsonStaff: it breaks the 100% rule for AdminStaff. studentID/staffIDforeign keys inTutoringSession.
The official answer official answer, released 26/27 Oct
The official answer is simpler than the stepper's model, and comparing the two shows how much detail the 15 marks really need.
Tutor only, a separate session class, the / derived count and multiplicities at both ends. Names are as the official answer wrote them.It differs in four places, and each of the stepper's choices is still defensible if you say why:
- Senior/junior is an attribute of the tutor, not an association class.
- School is a plain attribute of Student. The School class is fine but not needed for the marks.
- Abstract superclasses are not marked. Marking Person and Staff abstract is correct but optional.
- The student's multiplicity on the session is
1..*(every student has attended at least one session), with*students per session. The stepper reads it the other way: at least one student per session, possibly none per student. Both readings fit the text; the safest answer states its choice in a note.
Check yourselfWhy can't "each time students are tutored … the date/time and activity type" be an association class on Student — TutoringStaff?
Because an association class has exactly one instance per pair of linked objects, and the same student and tutor meet in many sessions. Each session needs its own date/time, so the session must be reified as a full class, TutoringSession, with ordinary associations to both sides.
Worked example B: 2021 S2 Q4, the car saleroom
The second past paper uses the same structure:
1. For all persons in the domain, we need to know their name, address and phone number. 2. For the customer we also need to know their budget, favourite car, and credit score. 3. For employees we also need to know their employee ID. 4. There are two kinds of employees, Sales Representatives and Mechanics. 5. Sales Representatives have a target number of sales per month, and can sell cars. Mechanics have a salary, a certain number of years of experience, and maintain cars in the saleroom. 6. A car has transmission type (either automatic or manual), a paint colour, and specific engine power. A car is purchased by one customer, who can own any number of cars.
- Six sentences again, with the familiar "for all … also … two kinds" pattern. Expect a two-level hierarchy and one central thing (the car) that the people are related to.
- Sentence 1 →
Person {abstract}with the common attributes name, address and phoneNumber. Persons are customers or employees, so the partition is complete. - Sentence 2 →
Customerwith the extra attributes.budgetis a quantity with a unit, so it uses theMoneydata type. "Favourite car" is left for later, because it involves the Car class. - Sentence 3 →
Employee {abstract}withemployeeID. The ID is allowed because it identifies the employee itself; it is not a foreign key to another class. Employee is abstract because sentence 4 gives a complete partition. - Sentence 4 →
SalesRepresentativeandMechanicunder Employee, sharing one triangle. Sentence 5 will give each extra attributes and associations, which justifies the subclasses. - Sentence 5, attributes:
targetSalesPerMonthfor the rep;salary : MoneyandyearsOfExperiencefor the mechanic. - Sentence 6, attributes →
Car. "Either automatic or manual" signals an enumeration,transmission : {automatic, manual}, which is also the official choice. AutomaticCar/ManualCar subclasses would add nothing, though the official answer notes subtypes as an accepted alternative. Paint colour is a data type; engine power is a quantity with a unit (kW), soPower. - Sentence 5, verbs →
SellsandMaintains. A rep sells many cars, and a car is sold by at most one rep (0 while unsold):SalesRepresentative 0..1 —Sells— 0..* Car. Maintenance is many-to-many, but there is no data about the maintenance itself, so no association class is needed. - Sentence 6, last clause →
Purchases. "Any number of cars" gives0..*at the Car end; "one customer" gives 1 or 0..1. Choose0..1because unsold cars have no purchaser, and note the assumption. "1" is also defensible if only sold cars are considered (1 vs 0..1 is context dependent). - Sentence 2, favourite car →
Has-as-favourite. A car is not a number or text, so relate it with an association. This gives two associations between the same pair, each separately named. If "favourite car" just means a model name unrelated to the cars in stock, a text attributefavouriteCaris defensible, and that is the official answer's choice: the attribute is the safe option, the association the ambitious one. - Check and stop. Every sentence is covered. The saleroom has no sentence of its own, is a container with no required information, and there is only one, so
Saleroom 1 —Displays— 0..* Caris optional. ASaletransaction class would only be justified if the question asked for a sale date or price; it doesn't, so by the mapmaker rule, don't add it.
The official answer official answer, released 26/27 Oct
Money, Power). Its note states the marking point outright.The differences from the stepper's model are all matters of judgement:
- Favourite car is a plain attribute of Customer.
Has-as-favouriteis a defensible reading, but the attribute is safe and needs no long justification. - Multiplicities. The official answer uses
1at the rep and customer ends, describing cars that have been sold;0..1also covers unsold cars. For maintenance it has each car maintained by0..1mechanic, where the stepper has many-to-many; the text doesn't decide this, so either is fine with an assumption. - No abstract markers and no conceptual data types. Both are correct additions, not requirements.
Check yourselfA new sentence 7 is added: "For each sale we need the date and the price paid." What changes?
Now a Sale transaction class is justified (business transactions are the first category on the list): Sale {date, price : Money} linked to Customer, Car and SalesRepresentative with named associations. It replaces the direct Purchases and Sells lines, since the sale now records who bought what from whom. Without such a sentence, adding Sale would break the mapmaker rule.
Reading the course's notation-reference example (University Club)
The course's notation reference draws a University Club model that shows almost every element the course expects in one diagram. It is redrawn in full in the appendix; be able to name each element:
Member is the superclass of CommitteeMember and RegularMember {membership_expiration_date}.Member * —enrolled— 1..4 Subject: at least one, at most four.Event * —◂ Attends— * Member: the ◂ says which way to read the name.CommitteeMember 1 —Creates— * Event sits on the subclass, because only committee members create events.CommitteeMember 1 —Has— * Position carries Appointment {date_of_commencement}.Position has subclasses President, GeneralCommittee and Treasurer (note: "One member only for each"); Treasurer 1 —Uses— 1 ClubAccount.- Work sentence by sentence: hierarchy from "for all … also … kinds of", attributes on the most general class, associations on the most specific class, multiplicities from the wording.
- "For each pairing" → association class; "each time" → event class; "the number of" →
/derived; "either … or" → enumeration. - Finish by ticking every sentence, stripping design notation and writing assumption notes. Different but justified answers earn the marks.
Common Domain-Model Mistakes exam
These are the mistakes that cost marks. The evidence comes from the Workshop 2 "NetFlicks" critique, the Workshop 11 revision slide, the Tony's Pizza videos and Larman. Use the list as a final check on your own diagram before you hand it in.
- Design or software elements, which the workshop calls the "biggest issues": visibility markers, methods, navigability arrows, programming types and software concepts (full table in §2.1).
- Missing association names or multiplicities. The Workshop 11 diagram had two unlabelled arrows into
TransactionLogger. - Foreign-key attributes, such as
personIDused to link, oritemIDinside another class's box, instead of an association. - A complex concept as an attribute (
destination,store,pizzaStyle : text), or the reverse: making a plain number or text into a class. - Unjustified subclasses: kinds that differ only by a value, states modelled as subclasses, and subclasses that break the 100% rule because an association sits on the superclass.
- Repeating inherited attributes in subclasses, or leaving common attributes in the subclasses instead of on the superclass.
- Skipping an intermediate concept. The Workshop 11 example has
Person —pays for→ Item, which bypasses the transaction (Sale/Payment) and the line item that the category list says to model first. - Weak association names, such as "Has", "Uses" or "Relates-to".
- Hollow-diamond aggregation everywhere. Use a plain association, or composition only when its three properties hold.
- Not covering every sentence, or adding things that are not in the text (the mapmaker rule).
- Leaving out multiplicity bounds the text states, such as "up to five", "at least one" or "1..4".
Mistakes 1, 4, 5, 8 and 9 already have bad/good pictures earlier in this Part. The gallery below shows the remaining ones side by side.
Set this against the list. In the Workshop 11 domain model every association is named, with a reading arrow (◄ ▲ ▼) where the layout is ambiguous, and has multiplicities at both ends taken from the text (1..16 zone units per control unit, 0..2 cameras and 0..2 flasher-sounders per zone). Kinds of sensor form an abstract Sensor hierarchy only because one kind, the configurable movement detector, has an extra attribute (threshold). States are enumeration attributes (zone_state : {active, inactive}), and assumptions such as "physically close: typically large room or adjacent rooms" are written in notes. There are no methods and no software classes. The - signs before its attributes are the drawing tool's default; leave them out of a hand-drawn domain model.
Check yourselfFind five mistakes: Member {+name : String, memberID, kind} with subclasses GoldMember and SilverMember (no attributes), and Member ──Has──▶ Loan with no multiplicities. The text says "gold and silver members differ only in their fee".
+is a visibility marker.Stringis a programming type.- GoldMember/SilverMember differ only by a value: replace them with an enumeration such as
level : {gold, silver}(and a fee attribute); the existingkindattribute even duplicates them. - The arrowhead is navigability; domain associations are plain lines.
- "Has" is a weak name, and multiplicities are missing at both ends.
memberID on Member itself is fine: it identifies the member, it is not a foreign key.
Before handing in: no design notation; every line named with multiplicity at both ends; no foreign keys; things as classes, values as attributes; subclasses only with a motivation; inherited attributes stated once; transactions and line items not skipped; every sentence ticked, and nothing extra.
System Sequence Diagrams exam · 10 marks
The domain model is static: it shows everything at once. Now we turn to behaviour: what the system does in one scenario, seen from the outside. Software must be designed to handle the events that arrive at it, so the first job is to list those events precisely. That is what a system sequence diagram does.
A system sequence diagram (SSD) is a picture that shows, for one particular scenario of a use case, the events that external actors generate, their order, and inter-system events. The system is treated as a black box, and the emphasis is on events that cross the system boundary. The lecture words it as "a visualisation of the system events that external actors generate, the order of the events, and possible inter-system events".
Why draw one
Larman says a system reacts to three things: external events from actors (human or computer), timer events, and faults or exceptions. An SSD makes the system events (input events) explicit, and each one implies a system operation, the system's handler for that event. Taken together, the system operations of all use cases form the system's public interface, which you can draw as a single class System. The 2021 S1 exam's Vending_Machine class is exactly such an interface: its public (+) operations are the system operations.
SSDs feed later work: they are input to operation contracts, to the glossary (for parameter and return details) and especially to object design. Throughout, they describe what the system does without saying how.
Relation to use cases and the UP
An SSD is derived from a use case and visualises one scenario, one path through it, so there is one SSD per scenario. Draw one for the main success scenario of each use case, plus any frequent or complex alternative scenarios, and only for the current iteration; each takes from a few minutes to half an hour. SSDs belong to the UP Use-Case Model and are created mostly in elaboration.
Name the SSD after the scenario, for example "Process Sale Scenario", and don't copy the use-case text into the diagram (the lecture slides place the text beside the SSD only to show traceability). The name matters because, as the Tony's Pizza video points out, an SSD is dynamic: it shows one interaction over time, unlike the static domain model.
Notation exam
The diagram below is Larman's inter-system version of Process Sale (ch. 32, lecture slide 35), with the system as :NextGenPOS and three supporting actors. The numbered badges are explained underneath.
:Sale, no :Register) ever appears.- Diagram name. A title, or an
sd ScenarioNameframe around the diagram. Always name it. - Primary actor on the left: a stick figure labelled
:Cashier. The colon means an anonymous instance of that role; a named instance such assteve:Customeris allowed but unusual. Other human actors (:Technician) are more stick figures; include every actor who sends an event in the scenario. - The system: one lifeline box,
:Systemor a name like:NextGenPOSor:VendingMachine. It is a black box: internal objects never appear. Each lifeline is a dashed line, and time runs downward. - Supporting (secondary) actors and other systems on the right, as boxes marked
«actor». Inter-system events go from the system to them. - System event: a solid line with a filled arrowhead, labelled
operationName(parameters); a synchronous message from an actor to the system. - Return: a dashed line with an open arrowhead back to the actor, labelled with the returned data. Optional if nothing is returned.
- Frames:
loop [guard]repeats; every loop needs a guard, otherwise it never ends (loop(n)is allowed).alt [cond1] … [else]gives mutually exclusive branches separated by a dashed line;opt [cond]runs only if the guard holds;ref ScenarioNamepulls in a separate diagram framedsd ScenarioName. - Inline return form:
reply = requestApproval(request)on the call is an alternative to a dashed return (Workshop 3 shows both). The external call is drawn as an ordinary synchronous message, an abstraction of whatever protocol is really used.
Three more elements complete the kit: a note (dog-eared box with a dashed connector) for assumptions, state changes and internal behaviour; a self-call from :System back to itself, which is the course convention for essential internal behaviour (explained below); and optional activation bars, which the course notation reference shows.
Naming system events and parameters exam
Name events at the level of intent, not the physical input device or medium, and start each name with a verb, because system events are commands or requests. The workshop review slide puts it this way: "Events should remain abstract/non-technical, show the intent for the action not the method."
| ✗ Physical or device level | ✓ Intent level |
|---|---|
scan(itemID) | enterItem(itemID, quantity) |
insertCash() | makePayment(amount) |
tapCard() | enterMykiCard(cardNumber) |
pressButtonB4() | selectProduct(…) |
Parameters carry the information the system needs, and they use the same names as the domain model. As the Workshop 2 solution says, "If you need a data element which is not present in the domain model, you should go back and add it to that model." Returns are what the actor perceives (a description, total, receipt or balance), abstracted from the presentation medium. And when an interface is given, as with the exam's Vending_Machine class, use its exact operation names and parameter types.
Two things stay out. Don't model login: authentication is assumed unless something special happens, because users rarely log in for just one activity and it clutters the diagram (Workshop 2 solution, Workshop 3 review). And put long explanations in the glossary, not the SSD; what a "receipt" contains is an example.
The exam convention: notes and self-calls exam
A pure Larman SSD shows only events that cross the boundary. But both past exam SSD questions add the instruction: "Include all external method calls, and use notes and/or self calls to describe internal … behaviour essential to the scenario." So in this course an SSD contains three kinds of content, and it is still a black box:
External calls
Every operation an actor or external system invokes on the system, and every call the system makes to an external system.Self-calls
Arrows from:System back to itself for essential internal steps: checking availability, computing a value, dispensing, printing. If an interface is given, use its private operation names: available(Product), value(Coin), dispense(Product), error().Notes
Internal state changes (state = outOfOrder), decisions (value 200 ≥ price 185 → coin accepted), real-world actions outside the system ("technician repairs the fault"), and assumptions.Never introduce internal objects, and never show how: no algorithms and no internal classes. Self-calls name what the system does internally, at the same intent level as the external events.
Method: scenario → SSD exam
- Identify the single scenario and write its name as the title or in an
sdframe. - Identify the participants. Primary actor on the left; any other human actors; exactly one
:System; external systems and devices on the right as«actor». - Walk through the scenario step by step. For each action the system must respond to, draw a system event (solid arrow, intent-level name, parameters). For each output the actor perceives, draw a dashed return. For each request to an external system, draw an arrow to that
«actor», with its reply dashed. - Add essential internal behaviour as self-calls and/or notes, including state changes.
- Add frames:
loop [guard]for "repeat until …",alt/optfor branches the scenario leaves open,reffor sub-flows drawn elsewhere. For a fully specified concrete scenario (as in the exams), draw the path linearly: don't add alt branches the scenario doesn't take, and draw repeated attempts twice. - Check that every message crosses the boundary (except self-calls), that names match the given interface or domain model, and that the question's concrete values appear (prices, coin value). Check arrow directions, dashed returns, and a guard on every frame.
Worked example: POS Process Sale (Larman Fig. 10.2, lecture)
This is the standard cash-only Process Sale scenario. Step through it to see each line of the use case turn into a message, or into nothing.
- Two participants: the primary actor
:Cashieron the left and the black-box:System. The customer never touches the system in this scenario, so they don't appear. - Step 1, "Customer arrives", involves no interaction with the system, so it produces no system event.
- Step 2, "Cashier starts a new sale" →
makeNewSale(). A verb-first, intent-level name with no parameters needed. - Steps 3–4: "enters item identifier" →
enterItem(itemID, quantity), using domain-model attribute names. What the system presents (description, price, running total) comes back as a dashed return. - "Repeats steps 3–4 until done" → a
loopframe around those two arrows, with the guard[more items]. Without a guard the loop would never end. - Step 5, "System presents total with taxes": the cashier signals the end of entry with
endSale(), and the total with taxes is returned. - Step 6, "Cashier tells Customer the total", happens between people, outside the system: no system event.
- Step 7, "Customer pays and System handles payment" →
makePayment(amount), returning change due and a receipt. The cashier enters the payment, so the arrow still comes from the cashier. - Name the diagram after the scenario: an
sd Process Sale Scenarioframe. Four system events, so four system operations to design later.
Worked example: Tony's Pizza "Place Order", with a ref frame
The Place Order main success scenario is steps 1–4 followed by "repeat steps 1–4 until done", so those steps sit inside a loop. Alternative 2a, "Customer edits pizza toppings", is a subfunction use case, so it gets its own diagram, pulled in with a ref frame.
ref frame spans both lifelines and points to a separate diagram with the same name.sd EditPizza with the same lifelines. The loop also covers an unmodified pizza: with zero adjustments, the body runs zero times.sd stands for "sequence diagram" (the video calls it a "sub diagram"). Mermaid can only mark the ref frame with a note, which is why the guide's sketches look different; on paper, draw it as above.
Worked example: Myki Quick Top-up (lecture exercise)
1. Traveller taps Myki card; machine displays balance. 2. Traveller selects the top-up amount. 3. Traveller pays by tapping a credit card. 4. Traveller taps the Myki card again to load the top-up; machine displays the new balance.
enterMykiCard and makeCreditPayment, not tapCard. The payment service lifeline is optional (the lecture's blank template has only the top-up machine), but including it shows an inter-system event. The note records an internal state change.Check yourselfA student's SSD for an ATM has the events insertCard(), pressKey(5), pressKey(0), pressOK(). Rewrite them.
These name the physical device, not the intent. At the level of intent: enterCard(cardNumber) (or similar) and withdrawCash(amount), with the amount as a parameter rather than one event per key press. Names start with a verb and use domain-model vocabulary.
Check yourselfWhy are steps 1 and 6 of Process Sale missing from its SSD?
Neither involves the system. "Customer arrives" and "Cashier tells Customer the total" happen between people in the real world, so no event crosses the system boundary and there is nothing for the system to handle.
- One SSD per scenario, named: actors left, one black-box
:System,«actor»systems right, time downward. - Solid filled arrows for intent-level, verb-first system events with domain-model parameters; dashed open arrows for returns.
- Frames need guards; in this course, self-calls and notes show essential internal behaviour without opening the box.
SSD Exam Questions and Common Mistakes exam
Both past papers set a 10-mark SSD question with the same shape: a machine, a short behaviour description, and one concrete scenario that goes wrong and then right. This section works through both, compares each with the official answer, and ends with the mistakes that cost marks.
2021 S1 Q3: the vending machine (10 marks)
The question gives the system interface as a UML class, Vending_Machine:
Vending_Machine
- selected : Product
- state : {waitingForSelection, waitingForCoin, refundingCoin, dispensingProduct, outOfOrder}
------------------------------------------------------------------
- available(Product) : boolean + cancel() : void
- dispense(Product) : void + dispensingComplete() : void
- display(Product) : void + insert(Coin) : void
- error() : void + refundingComplete() : void
- price(Product) : int + reset() : void
- refundCoin() : void + select(Product) : void
- value(Coin) : int
Reading the interface. The public (+) operations are the external system operations, each invoked by something outside the system: the customer invokes select, insert and cancel; the technician invokes reset; the dispenser and coin-return hardware invokes dispensingComplete and refundingComplete (it sits outside the controlling system, so it is a non-human actor). The private (−) operations are internal behaviour, drawn as self-calls. price and value return int, presumably cents, so $1.85 is 185 and a $2 coin is 200. error() is private because the fault arises inside the machine.
- On power-up, wait for a selection.
- Display the selected product and wait for a sufficiently high-valued coin.
- Lower-value coins are returned; high-value coins are accepted, with no change given.
- After payment, dispense the product.
- While waiting for payment, the customer may cancel.
- At any stage an error may put the machine "Out of Order" until the problem is corrected and the technician presses the internal reset button.
The customer gets an error after selecting potato chips ($1.85). A technician fixes the problem, and the customer then buys the chips with a $2 coin.
Question instruction: "Include all external method calls, and use notes and/or self calls to describe internal … behaviour essential to the scenario."
- Participants. Two human actors (
:Customeron the left and:Technician, who sendsreset), the machine named after the given class,:Vending_Machine, and on the right the dispenser hardware as an optional«actor». A note gives the starting state. - First selection.
select(potatoChips)uses the interface's exact name. The private operationsavailableanddisplaybecome self-calls; the displayed price comes back as a return, and a note records the new statewaitingForCoin. - The error. It comes after
select, while waiting for a coin.error()is private, because the fault arises inside the machine, so it is a self-call, not an actor message. A note recordsstate = outOfOrder. - The repair. The physical repair happens outside the system, so it is a note. But
reset()is an external call from the technician. Afterwards the machine is back inwaitingForSelection, its initial state, so the earlier selection is lost. - Re-selection. Because the selection was discarded, the customer must call
select(potatoChips)again: an essential, mark-earning detail that many students miss. - Payment.
insert($2 coin), then self-callsvalue(200) andprice(185). The note shows the concrete comparison: 200 ≥ 185, so the coin is accepted with no change.refundCoin,refundingCompleteandcancelare not used, because this scenario never takes those paths, so there are no alt frames. - Dispensing.
dispense(potatoChips)is a self-call; the state becomesdispensingProductand the chips reach the customer. - Completion.
dispensingComplete()is public, so this diagram draws it as an external call from the dispenser hardware; the state returns towaitingForSelection. The official answer draws it as a self-call instead, and both are acceptable. - What earns the marks (gold): the external calls with the given names and arguments (
select,insert,reset), the two human actors, the correct order including the re-selection after reset, private operations as self-calls, and the concrete prices in a note.
The official answer is leaner, and it corrects one claim the guide used to make. It has three lifelines: :Customer on the left, the system drawn as :Vending_Machine in the middle, and Technician on the right. The customer sends select(Chips) and the machine immediately self-calls error() (no available/display before the error). The technician sends reset(). The customer sends select(Chips) again; the machine self-calls available(Chips) : boolean (note: "Must be true as per scenario") and display(...). The customer sends insert(TwoDollarCoin); the machine self-calls value(TwoDollarCoin) : int, price(Chips) : int (note: "price = $1.85; $1.85 < $2.00"), dispense(Chips) and finally dispensingComplete(), also as a self-call. There are no dashed returns at all, and a note says "the return type (e.g., int, Boolean) is not necessary". (Its second display call reads display(PopCorn), a slip for Chips.)
So the dispenser as a third actor is optional, not a marking requirement: the official answer treats dispensingComplete() as the machine's own call. Drawing it as an «actor» is still defensible because the operation is public. The dashed responses and state notes are good practice that the official answer does without. Naming the lifeline after the given class, :Vending_Machine, is a small touch worth copying.
2021 S2 Q5: the fuel dispenser (10 marks)
The customer selects diesel ($1.60/L), but the selected tank is empty. The service attendant then manually switches the machine to a new tank. The customer selects diesel again, and this time the machine reports it is available, dispenses fuel, and displays the total price. The customer pays by credit card and the machine processes the payment. Finally, the attendant verifies the payment, the machine prints a receipt, and the customer collects it.
No interface is given, so you must invent intent-level operation names and keep them consistent. There are three actors: :Customer (primary, left), :ServiceAttendant (a second human actor whose manual actions are system events) and, on the right, «actor» :CreditAuthorizationService, which makes "the machine processes the payment" visible as an inter-system call (a self-call processPayment(...) plus a note is an acceptable simpler alternative). Internal behaviour (checking the tank level, dispensing, computing the total, printing) is shown as self-calls. The first attempt fails and the second succeeds, drawn in sequence with no alt frame, because the scenario is fully specified. Litres are not given, so the total is shown as litres × $1.60 with an illustrative value.
startDispensing/stopDispensing model the nozzle trigger at the level of intent (a single dispenseFuel() plus a note on metering is also fine). The alert to the attendant is an assumption explaining why the attendant acts. collectReceipt() is included because the question asks for all external calls; a note would be weaker but acceptable.It confirms the structure but is simpler. Three lifelines, Customer, Fuel Dispensing Machine and ServiceAttendant, with no external payment service, and every message numbered in decimal style, worth copying because it makes the order unmistakable:
selectFuel(diesel)from the customer, then the self-call1.1: available(diesel) : boolean, annotated "Has to return false".changeDispensingTank()from the attendant.selectFuel(diesel)again, then self-calls3.1: available(diesel) : boolean("Has to return true"),3.2: dispenceFuelToVehicle()and3.3: displayTotalPrice().payForFuel(credit card)from the customer, then the self-call4.1: processPayment().verifyPayment()from the attendant, then the self-call5.1: printReceipt().collectReceipt()from the customer.
The differences are all defensible: the official answer has no payment service, no nozzle events, no alert and no illustrative total, and no return arrows; it uses notes ("has to return false/true") to pin down the values the scenario fixes. The essentials for the marks: two human actors, every customer and attendant action as an external message (including the second selectFuel and the final collectReceipt), the machine's work as self-calls, and the failed and successful availability checks made visible.
Check yourselfIn the vending scenario, why must select(potatoChips) appear twice, and why is there no alt frame for a low-value coin?
After reset() the machine returns to its initial state, waitingForSelection, so the first selection is lost and the customer must select again. There is no alt frame because the scenario is fully specified: the coin is $2 and the price $1.85, so the low-value branch never happens. For a concrete scenario, draw the path linearly.
Check yourselfAn interface lists + insert(Coin) and - value(Coin) : int. How does each appear in the SSD?
insert is public, so it is an external call: a solid arrow from the customer to the system, named exactly insert(...). value is private, so it is a self-call on the system lifeline, ideally with its result shown (→ 200) or noted.
Common SSD mistakes exam
- Opening the black box. Lifelines such as
:Sale,:ProductCatalogor:Databasebelong to a design sequence diagram. As Workshop 3 puts it, "a system sequence diagram visualises a use case, while a design sequence diagram visualises interactions between software objects." - Physical, UI-level or implementation names:
scan,clickOK,tapCard,pressButton,HTTP POST. Snake_case (as in the workshop solution) is tolerated, but camelCase verbs follow Larman. - Not using the given operation names or parameter types when an interface is provided.
- Missing actors: forgetting a second human actor (technician, attendant). An external device or service may be drawn as an actor, but both official answers show that work as self-calls, so it is optional.
- Wrong arrow styles: solid lines for returns, returns pointing at the system, or messages to an actor that are really that actor's own actions.
- Frames without guards, or loops and alts that don't match the scenario; don't use
altfor paths the concrete scenario never takes. - Mixing several scenarios in one SSD, or not naming the diagram.
- Showing login or other routine steps that add nothing.
- Omitting concrete values given in the question (prices, coin value), or the essential internal behaviour the question asks for via notes or self-calls.
- Inconsistent names with the domain model: parameters whose names don't match its classes and attributes.
:Register, :Sale and :ProductCatalog are software objects: that is a design sequence diagram, not an SSD. And scan names the barcode reader rather than the intent.| System sequence diagram | Design (object) sequence diagram (Part III) | |
|---|---|---|
| Purpose | Analysis: what events enter the system | Design: how objects collaborate to handle a system operation |
| Lifelines | Actors + one :System (+ external systems) | Software objects (:Register, :Sale, …) |
| Messages | System events / system operations | Method calls between objects |
| Derived from | One use-case scenario | One system operation from an SSD (+ contract, domain model, GRASP) |
Check yourselfAn SSD has a dashed arrow labelled selectFuel(diesel) from :System to :Customer. What is wrong?
Two things. The customer sends the selection, so the arrow must go from the customer to the system; and a system event is a solid line with a filled arrowhead. Dashed lines with open heads are for returns only.
- Use the given interface: public operations are external calls with their exact names; private ones are self-calls.
- Draw the concrete scenario linearly, including repeats (the second
select), with the question's values in notes. - Never open the black box, never name the device, and give every frame a guard.
Operation Contracts lower exam priority
An SSD names each system operation but says nothing about what it does to the domain. An operation contract fills that gap: it states precisely which domain objects exist, change and get linked once the operation has run. Contracts appear in the course slides only in the UP artefact diagram, and no past exam asks for one, so know the definition, the sections and the postcondition kinds, and use contracts as a thinking tool for "what must the design achieve?"
An operation contract uses a pre- and post-condition form to describe the detailed changes to objects in the domain model caused by one system operation (one of the operations from an SSD). It describes what changes, not how. Contracts are an optional part of the UP Use-Case Model.
The four sections
enterItem(itemID : ItemID, quantity : integer).Postconditions: photographs of the stage
By definition, postconditions describe changes in the state of objects in the domain model. They are observations true after the operation, not actions performed during it. Larman's stage-and-curtain analogy makes this concrete: photograph the stage, close the curtain, run the operation, open the curtain and photograph again. The postconditions are the differences between the two photos. The stepper does exactly that for enterItem(100, 5).
- Photo 1. A sale is underway (that is the precondition), and the catalog's ProductDescription with itemID 100 exists. They are not linked. Now close the curtain and run
enterItem(100, 5). - Instance creation. The second photo contains an object that wasn't there before. Name it, sli, so the later postconditions can refer to it.
- Association formed. The new line item is linked to the current Sale. Strictly, what is formed is a UML link, an instance of the association.
- Attribute modification. sli's quantity is now the value passed in. Note the past tense: "became", not "set".
- Association formed, again. The line item is linked to the ProductDescription whose itemID matches the parameter.
- The most common mistake is forgetting to form associations, especially for newly created instances. Two of the four postconditions here (gold) are links; a contract with only "sli was created" would leave the line item floating, attached to nothing.
The five kinds of postcondition
Larman lists five kinds, grouped into three categories:
| Category | Kind | Example |
|---|---|---|
| Instances | 1. Instance creation | "A SalesLineItem instance sli was created." |
| 2. Instance deletion (rare) | Records of a bankruptcy were destroyed after the legal period. | |
| Attributes | 3. Attribute modification | "sli.quantity became quantity." |
| Associations (links) | 4. Association formed | "sli was associated with the current Sale." |
| 5. Association broken (rare) | A line item removed from a sale, a loan paid off, a membership cancelled. |
- Write in the past tense, as declarative, passive statements: "A SalesLineItem was created", not "Create a SalesLineItem" or "A SalesLineItem is created".
- Name new instances (sli, pmt) so later postconditions can refer to them.
- Use plain natural language. OCL is possible, but Larman advises against it without a compelling reason.
- Use domain-model names. Postconditions can only create instances of domain-model classes and form domain-model associations, so if a contract needs something the model lacks, update the domain model. Writing
endSalerevealed the need forSale.isComplete, for example. All artefacts evolve iteratively.
When to write contracts. Only for complex or subtle system operations whose effects are unclear from the use case; Larman's example is an airline addNewReservation. If developers understand the operation without one, skip it; Larman notes that most POS contracts are educational only. To create them: (1) identify the system operations from the SSDs, (2) write contracts for the complex ones, (3) describe their postconditions using the five kinds.
Two examples
The POS contract for enterItem, the one the stepper photographed, written out in full:
Contract CO2: enterItem
Operation: enterItem(itemID : ItemID, quantity : integer)
Cross References: Use Cases: Process Sale
Preconditions: There is a sale underway.
Postconditions: - A SalesLineItem instance sli was created. (instance creation)
- sli was associated with the current Sale. (association formed)
- sli.quantity became quantity. (attribute modification)
- sli was associated with a ProductDescription,
based on itemID match. (association formed)
And an exam-style contract written against the tutoring domain model from §2.7:
Contract: recordTutoringSession
Operation: recordTutoringSession(dateTime, activityType, students, tutorsWithRoles)
Cross References: Use Cases: Record Tutoring Session
Preconditions: The students and tutoring staff involved are known to the system.
Postconditions: - A TutoringSession ts was created.
- ts.dateTime became dateTime; ts.activityType became activityType.
- ts was associated with each Student in students.
- For each (tutor, role) in tutorsWithRoles, a TutorParticipation tp was
created linking tutor with ts, and tp.role became role.
(Student./numberOfSessions is derived, so no postcondition updates it.)
Link to design. Postconditions tell the designer which objects must be created and linked, which feeds the GRASP Creator and Information Expert decisions (Part IV). "sli was created and associated with the Sale" suggests that Sale creates SalesLineItem.
Check yourselfFix these postconditions for makePayment(amount): "Create a Payment. Set its amount."
Past tense, passive, named instance, and don't forget the link: "A Payment instance pmt was created. pmt.amountTendered became amount. pmt was associated with the current Sale." The original is written as actions (imperative) and forgets the association, the most common mistake.
Check yourselfWhy does the tutoring contract have no postcondition updating /numberOfSessions?
Because it is a derived attribute: it is computed from the student's linked sessions. Forming the link between the session and each student already changes the count, so stating it separately would be redundant.
- A contract has Operation, Cross References, Preconditions and Postconditions; the postconditions matter most.
- Postconditions are past-tense observations of domain objects: instance created/deleted, attribute modified, association formed/broken.
- Name new instances, use domain-model names, and never forget the associations.
One-Page Summary for Your Notes Sheet
You may take two double-sided A4 pages into the exam. This is the material from this Part that earns its place on them.
What it holds
Conceptual classes, attributes and associations. No operations, visibility, software types, navigability, foreign keys or software components. Verb-phrase names, multiplicity at both ends, no arrowheads (a ▸ reading aid is OK).Three strategies
Reuse existing models; the category list (start with transactions); noun phrases, with care. Description classes stop information disappearing when instances are deleted.Number-or-text test
Not a number or text in the real world → a class. Relate classes with associations, never with attributes.When to subclass
Extra attributes or associations, handled differently, or (if animate) behaves differently; must pass the 100% and Is-a rules. Value-only differences → enum attribute; states are not subclasses. Abstract when every instance belongs to a subclass: italics or{abstract}.Association class
Dashed line to the association; for many-to-many plus data, or data whose lifetime is tied to the link. Same pair can repeat → a full event class.◆, ◇, /name, [key]
Composition ◆ at the whole for exclusive parts it creates and deletes; avoid aggregation ◇. Derived/name. Qualifier [key] reduces the far multiplicity. Reflexive associations need role names.One scenario, one black box
Actors left, one:System, external systems right («actor»). Solid arrows: intent-level, verb-first events with parameters; dashed returns. loop/alt/opt with guards; ref + sd for sub-flows; notes and self-calls for internal behaviour and state. Use the given operation names and concrete values.Before and after
Operation, Cross References, Preconditions, Postconditions. Five past-tense kinds: instance created or deleted, attribute modified, association formed or broken. Don't forget the associations.- Domain model (15 marks): sentence by sentence → hierarchy, attributes up, associations down, multiplicities from the wording, association classes and derived attributes, tick every sentence, strip design notation, note assumptions.
- SSD (10 marks): name it; actors and one system; every external call with the given names; private operations as self-calls; state and values in notes; the concrete path drawn linearly.
Analysis describes the problem: the domain model gives the vocabulary, the SSD gives the system operations, and contracts give their effects. Next, Part III opens the black box and designs the objects that handle each system operation.