Object-Oriented Analysis and the Domain Model
# Object-Oriented Analysis and the Domain Model
8.1 Object-Oriented Analysis as Decomposition of the Problem Domain
8.1.1 What Analysis Does After Requirements
Hook — why this matters: After weeks of gathering requirements you have a pile of stories and diagrams. How do you cross the bridge from "what the customer said" to "what we will build" without losing meaning? Analysis is that bridge — and object decomposition is how you walk it.
Object-oriented analysis (OOA) does not start from a blank page. It starts after requirements work is judged complete. In this course that means the System Information Specification (SIS) — the agreed textual record of what the system must do — is ready, and the functional requirements have been captured chiefly as use cases written from the actor's point of view. The team now shares a picture of the problem domain — the slice of the real world the system must support — and the first job of analysis is to understand that domain deeply and then break it into a coherent set of collaborating objects.
Two requirements artifacts are explicitly named as starting material:
- Use case: a narrative that captures a functional requirement as a structured story — actor, goal, main flow, extensions — in the actor's language. It answers "who wants what value and what steps yield it?"
- Activity diagram: a flow-oriented view of work (actions, decisions, forks, joins) that shows the sequence and branching of work before any objects are assigned. Think of it as the choreography before you cast dancers.
Both become object-discovery material. You read the use cases to hear who participates, and you consult the activity diagram to see where work flows between participants.
Intuition — two ways to cut a cake: Function-oriented decomposition is like slicing a cake by steps: "first beat eggs, then fold flour, then bake." Each slice is a function; data flows between steps. Object-oriented decomposition is like dividing the kitchen by roles: the Baker, the Oven, the Recipe Card, the Ingredient Shelf — each owns data and does its share of the steps. When the menu changes, re-slicing steps creates ripple edits everywhere; regrouping roles keeps change local because each role hides its details. Where the analogy breaks: In baking, steps and roles overlap less than in software — a real baker does many steps, but in OO each object strictly owns its responsibilities. Also, software objects persist (state) while recipe steps do not.
Formalize — what "decompose into objects" means
An object here is a domain participant with identity (you can point to this specific one), state (information it remembers over time), and purpose (the work it contributes to solving the current requirement). A class groups similar objects under one name and definition.
OOA as decomposition therefore means: given the SIS and its use cases, identify the set of domain concepts — persons, places, events, catalogs, transactions, rules, records — that together can realize every required story through collaboration. The decomposition is guided by three properties:
- Domain grounding: each object name is a word people in the domain already use (guest, reservation, sale, payment), kept consistent via a glossary — a shared list of terms with plain definitions that the whole team honors.
- Vocabulary continuity: the same names carry forward through analysis → design → programming. You do not rename "Reservation" to "BookingRecord" in design and "ResvObj" in code. That continuity is deliberate so learning in one phase transfers.
- Collaboration focus: objects are not isolated nouns; they are chosen because they must work together to make the use-case steps happen. The question is not "list all nouns" but "which participants, talking through which relationships, can enact these stories?"
Worked example — same requirement, two decompositions
Requirement (common to all domains below): a guest books a room for specific nights, pays, and receives confirmation.
Function view (what steps?): 1. Validate dates → 2. Check availability → 3. Calculate rate → 4. Record booking → 5. Process payment → 6. Send confirmation. Data flows between functions; the "guest" is just a data field flowing through.
Object view (who collaborates?): Guest requests Reservation; Reservation covers Stay; Stay uses Room; Room typed by RoomType; RatePolicy prices Stay; Payment settles Reservation; Receptionist (or System) coordinates. Each object hides its own state (Room knows its status; RatePolicy knows seasonal rules) and offers work related to its purpose. Steps still happen but now they are conversations between owners, not anonymous functions.
Apply the same lens to other running domains: point-of-sale terminal (Customer, Sale, SalesLineItem, ProductDescription, Payment), ATM (Card, Account, Transaction, Branch), library (Patron, Title, Copy, Loan), restaurant (Party, Table, Reservation, MenuItem). Domain changes; the question "who are the participants and what do they own and do?" does not.
Scope and assumptions — when this decomposition applies
Assumes: requirements are already agreed and the SIS / use cases are readable; you are solving the current iteration's problem, not an imagined future one; domain experts are available to validate the glossary. Applies: information systems where domain vocabulary is rich and stable enough to anchor design. Breaks / caution: if requirements are still vague, object decomposition prematurely freezes nouns you have not validated — go back to use-case writing first. If the domain is essentially algorithmic with little persistent state (e.g., a numeric solver), function-centric decomposition may be simpler.
Visual intuition: imagine a two-column picture. Left column labeled "Functions" shows a vertical pipeline of boxes (Validate → Check → Price → Record) with data arrows between them. Right column labeled "Objects" shows a circle of icons (Guest, Reservation, Room, Payment, Receptionist) connected by named lines (requests, covers, assigned to, settled by). A flow arrow snakes through the circle, touching each participant in turn. The takeaway: pipeline emphasizes order; circle emphasizes who owns what and where the flow must coordinate.
Pitfalls
- Renaming between phases. Inventing new synonyms in each phase ("Customer" in analysis becomes "Client" in design) quietly reintroduces the representation gap you were trying to shrink. Fix: enforce the glossary as a gate on every new diagram.
- Starting decomposition before the SIS is stable. You will model narrative color that later turns out irrelevant. Fix: require that the originating use case is reviewed before mining it for objects.
- Treating "decompose into objects" as "list every noun." A noun list is a starting candidate list, not the model. Every candidate must pass a purpose/identity test before it earns a class (see 8.3).
Q: We have finished requirements and created the System Information Specification. How do we move from that to objects? A: Start from the use cases. Read each story to understand its flow (using the activity diagram as a flow check), then look for the participants that appear in the story. Decomposition is judgment, not a formula: for each piece of the problem domain ask, "Is this a separate thing with its own identity and purpose that helps solve the current iteration's requirement?" If yes, it is a candidate object; if it is just a value held by another thing, it is likely an attribute. The activity diagram and glossary keep that judgment grounded.
Recap + bridge: OOA is the disciplined step after requirements that turns stories (use cases) and flow views (activity diagrams) into a domain-grounded set of collaborating objects, using the same vocabulary that will survive through design and code. This first cut is deliberately scoped to the current iteration — you will refine, not replace, these participants in 8.2 when you draw the domain model that makes the collaboration visible.
Real-world and domain connection: In hospitality (resort booking), retail (point-of-sale), and banking (ATM), teams that kept domain names end-to-end reported faster onboarding and fewer defect-discovery meetings, because a business stakeholder can read the model and say "that's not how a reservation covers a stay here." That tight loop between domain language and software structure is the primary economic payoff of object decomposition; technically it also supports low coupling, because hidden complexity stays inside the owning object rather than scattering as global functions.
8.1.2 Analysis, Design and Programming Share One Vocabulary
Formalize — one vocabulary, progressively refined
The lecture makes a single point repeatedly because beginners often miss it: analysis, design and programming use the same object idea. You do not invent a fresh set of objects for each phase.
- Analysis: first cut — identify conceptual classes that exist in the real domain, name their purpose, note high-level responsibilities without methods, and show associations in domain language.
- Design: detailed assignment — add responsibilities as operations (method signatures), decide visibility, navigation direction, patterns, persistence and performance choices. The conceptual classes remain recognizable; some may split or merge but the names stay.
- Programming: realization — implement the designed classes, choosing data structures and language idioms. The conceptual lineage is still traceable "Reservation → Reservation class."
This continuity is intentional. It lowers cognitive load (learn the domain once, refine thrice) and supports traceability (a design decision can be explained as "because in the domain a Reservation covers a Stay").
Intuition — draft, blueprint, building: Think of analysis as a site survey with stakes in the ground marking where the building's major rooms will be, named in the client's words (lobby, guest room, kitchen). Design is the architectural blueprint that adds dimensions, wiring, and materials while keeping the room names. Programming is the built building — studs and plumbing that realize the blueprint. You would not rename "lobby" to "entrance module" midway; you refine what "lobby" means and contains. The same applies to a domain concept across OOA/D/P.
Scope — iterative discipline
Assumes: work is organized in iterations (as in the Unified Process), each with scoped use cases. Applies: you refine within the current iteration's requirements and then extend iteration by iteration. Breaks: trying to identify every possible object for all imagined future needs at once — a form of up-front "waterfall modeling" — creates analysis paralysis. Guideline from Larman (T1 Ch.9): spend no more than a few hours on the early domain model per iteration; it will never be fully correct and the return on over-modeling is near zero. That time box forces the "good enough for this iteration" cut.
Visual intuition: three stacked horizontal lanes labeled Analysis (top), Design (middle), Programming (bottom), with a vertical column of class names (Reservation, Room, Payment, Guest) running through all three. As you move down, the box for each name gains detail — analysis box shows only name and a one-line purpose; design box adds operation compartments and associations with multiplicities and navigation arrows; programming box adds field types and method bodies. Arrows labeled "refine" point down between lanes. Takeaway: identity and name are stable; detail grows.
Pitfalls
- Treating analysis as "find them all." The urge to be complete leads to a model with dozens of speculative classes outside the iteration boundary. Fix: gate every class with "does the current iteration's use cases need it to remember or do something?"
- Letting design rename analysis concepts prematurely to fit a framework or database table naming convention. Fix: keep conceptual names in the domain model; let design add mappings rather than renames.
Recap + bridge: One domain vocabulary carries forward and matures across analysis, design and code by iterative refinement within a bounded iteration. That sets up 8.1.3, which contrasts what changes when you choose objects over functions as your decomposition lens.
Real-world and domain connection: Teams practicing iterative UP or Scrum that time-box domain modeling to a whiteboard sketch and then codify the same names in the domain layer of their Design Model (e.g., a Sale, Payment, ProductDescription package in a POS system) find that new iteration planning becomes vocabulary-driven — "this iteration we add Handling Returns, so we add Receipt and Return concepts to the same model" — rather than requiring a fresh analysis language each sprint.
8.1.3 Functional Versus Object Decomposition
Formalize — two lenses on the same requirement
- Function-oriented analysis: ask "what steps (business processes, functions) happen?" Decompose a big function into smaller Data Flow Diagram (DFD) processes, track inputs/outputs, then map processes onto modules. The primary structure is the process hierarchy.
- Object-oriented analysis: ask "which things exist, what do they know, and how do they collaborate to make the steps happen?" Decompose the problem domain into objects/classes (persons, places, events, catalogs, transactions) and the associations (real-world connections) that let them interact to realize each use case. The primary structure is the collaboration graph.
User requirements themselves can be expressed from different viewpoints: C-requirements (customer-facing — value in the customer's language) and D-requirements (developer-facing — system specification in implementation-aware language). The same requirement can be written either way. OOA chooses the developer-facing view to be object-centric and then demonstrates, via collaboration, how those objects enact the customer-facing stories. That choice produces the smaller representation gap (see 8.7): the names in the model match the names people in the domain use in everyday speech, so less translation is needed between mental model and software model.
Why that matters: OO's claimed advantages — managing complexity by hiding it inside owning objects, and supporting ease of change via low coupling — follow directly from this lens. When requirements change, you often add or adjust a collaboration, not rewrite a global process tree.
Comparison — Functional vs. Object Decomposition
| Dimension | Function-Oriented | Object-Oriented |
|---|---|---|
| Core question | What steps happen, in what order? | Who are the participants and how do they work together? |
| Primary artifact | Process / DFD hierarchy, data flows | Conceptual classes + associations + glossary |
| Element identity | Step or transform, defined by inputs/outputs | Domain concept with identity, state, and purpose |
| Handling of data | Data flows between processes; often global or passed | Data owned by the object that participates; hidden |
| Change response | Add/modify functions; data-flow rerouting | Add/modify collaborating objects or associations |
| Readability to domain person | Needs translation ("Process 2.3 validates reservation") | Direct ("Reservation covers Stay") |
| Gap to code | Large — functions map to procedures, data to separate structures | Small — domain names become class names (with refinement) |
When to pick which: If the problem is fundamentally a pipeline of stateless transforms on streams (e.g., compiler passes, signal processing chains), a functional decomposition may be clearer. If the problem is a rich domain of long-lived participants that remember state and interact over use cases (retail, booking, banking, catalog), the object lens wins on clarity and evolvability. Many systems mix both — pipeline inside a control object is common — but analysis starts with objects for information systems.
Pitfalls
- Calling D-requirements "technical jargon" and skipping them. D-requirements are not jargon for its own sake; they are the developer's precise, testable statement of what the system must do. Skipping them leaves analysis anchored only to customer stories.
- Equating "use case steps" with "methods." A use-case step is a domain event; a method is a software operation owned by one class. Mapping them 1:1 prematurely bypasses the responsibility-assignment reasoning that design exists to do.
Recap + bridge: Functional decomposition organizes steps; object decomposition organizes participants and their collaborations. OOA bets that the latter gives you a smaller gap between domain talk and software and better-hidden complexity — a bet the rest of the lecture tests by building the domain model (8.2) and applying purpose and pruning tests (8.3–8.8).
Real-world and domain connection: Legacy C-style retail systems often modeled "process sale" as a single procedure with shared record structs; adding loyalty pricing meant editing that procedure and every report that read its structs. OO POS redesigns (as in Larman's case study, T1 Ch.6–9) assign pricing to a PricingStrategy hierarchy and sale state to a Sale aggregate — new pricing rules become new strategy objects, not edits to a central procedure, illustrating the practical payoff of decomposing by participants.
8.2 The Domain Model and the Conceptual Class Diagram
8.2.1 What the Domain Model Shows
Hook: Look at a UML diagram full of rectangles and lines. Is it a picture of your future code? In analysis, not yet — it is a picture of the world your code must inhabit. Why draw it then?
Formalize — definition and notation
A domain model — also called a conceptual class diagram or analysis class diagram — is a visual dictionary of the noteworthy concepts in the problem domain, drawn with the same rectangle-and-line notation as a UML class diagram but with a different intent.
What it shows (conceptual perspective, Fowler; UP artifact — T1 Ch.9):
- Conceptual classes — ideas, things, or objects in the real domain that matter for the current iteration (e.g., Sale, Payment, Reservation, Room, Guest). The box shows the class name in domain vocabulary.
- Attributes — logical data values remembered about the concept, only where already known (e.g., Sale
date,time; ProductDescriptionprice). Many classes legitimately have no attributes yet — you know the concept exists and its purpose, but have not discovered its data. - Associations — named, real-world connections between conceptual classes (e.g., Sale
Paid-byPayment, Roomassigned toReservation). At this stage associations are plain, named lines (no aggregation/composition adornments, no inheritance, no navigability decisions) labeled with the domain's verb phrase.
What it does not show (by rule):
- Methods / operations — behavior is deliberately absent. You may note a high-level responsibility in prose, but you do not add method signatures, visibility, or navigation direction; those are design decisions.
- Software artifacts — no windows, databases, frameworks, or implementation classes. A POS domain model shows a real Register, not a Java
JFrame; an Inventory concept, not aSalesDatabasetable.
The model is static — a snapshot of concepts, their information, and their real-world links — and it is scoped: it aims to represent completely, for the current iteration, just enough of reality to solve the stated requirement. Every box and line must earn its place by helping answer "how does this set of concepts, collaborating, solve the current use cases?" It also serves as a source of inspiration for software design: the conceptual classes (and their names) inspire — but are not identical to — the software classes in the design model's domain layer (T1 Fig. 9.6). Lowering that name gap has been shown, since the 1990s Smalltalk experience cited in T1 Ch.9, to lower comprehension and change cost.
Intuition — visual dictionary, not blueprint: Think of the domain model as a labeled map of a neighborhood drawn in street names residents actually use (Main St, Library, City Park) rather than a contractor's construction plan (rebar specs, wiring runs). Residents can read the map and correct it ("that alley is not a street"). The contractor later adds construction detail while keeping the street names. Asking a domain model to show methods is like asking a street map to show plumbing — wrong concern at this stage. Break point: unlike a real map, the domain model is deliberately selective — it omits out-of-scope streets entirely, even if they exist in the wider city.
Worked example — POS domain model as visual dictionary (T1 Ch.9, Fig. 9.2)
Partial POS model for the cash-only Process Sale iteration:
- Classes:
Register,Store,Sale(attributes:date,time),Payment(attribute:amount),SalesLineItem(attribute:quantity),ProductDescription(description,price,itemID),Item(serial number),ProductCatalog,Cashier,Customer,Ledger. - Typical associations (all "need-to-remember" links):
SaleContainsSalesLineItem(1 to 1..),SalesLineItemRecords-sale-ofItem(or viaProductDescription),SalePaid-byPayment(1 to 1),SaleCaptured-onRegister,RegisterHousesStore,ProductCatalogDescribes*ProductDescription. - Reading test: Two-way exercise used in the lecture — (a) read the diagram and write five plain sentences: "A Sale contains one or more SalesLineItems; each SalesLineItem records sale of an Item; a Sale is paid by one Payment; a Sale is captured on one Register; a Store houses one or more Registers." (b) Reverse: read a textual problem and draw the diagram, checking that each sentence maps to a named line and that no isolated box remains without a connection that supports a use-case step.
Sense-check: If you removed associations, the diagram collapses to a glossary list — a list of nouns without the collaboration that achieves a sale. Adding named associations turns it into a picture of how the stories happen.
Scope and assumptions
Assumes: you have scoped the model to the use cases under design for the current iteration (UP guideline, T1 Ch.8–9). Applies: every visible element must trace to an information need in those stories. Breaks if: you expand to "the whole business" (BOM) or add software decisions (methods, navigation, visibility) — the diagram then stops being a domain conversation and starts driving premature implementation choices. Guideline: time-box early modeling to a few hours and accept the model will never be fully "correct."
Visual intuition: imagine a whiteboard with gray rectangles (classes) and thin black lines (associations) each labeled with a verb phrase in plain words. Attributes sit in the lower compartment of each rectangle, often just one or two per box; several boxes are deliberately empty below the name line ("attributeless at this stage"). No method compartment exists. The board is surrounded by sticky notes that are the glossary entries — when someone questions "what is a Sale?", you point to the glossary, not the diagram. Takeaway: the picture is intentionally light — just enough to ground conversation and inspire the later design layer.
Pitfalls
- Mimicking a design diagram: Adding methods, visibility symbols (-, +), or navigation arrows now makes the diagram look precise but strips its domain readability and commits you to design choices before you have walked the collaborations.
- Inflating with attributes speculatively: Inventing
customer.loyaltyTierbecause "we might need it" adds noise not demanded by the iteration. Attributes enter only when a use case implies you must remember that information (T1 9.16 —
"include attributes that requirements suggest or imply a need to remember").
- Accepting empty boxes without purpose: An attributeless class is allowed, but only if you can state its purpose. "We need Guest to track stays and settlements" passes; "We added System because something must hold everything" fails the purpose test.
Real-world and domain connection: In Larman's NextGen POS (T1 Ch.3,5,9), the same domain model — Sale, Payment, ProductCatalog, etc. — serves retail analysis and then inspires the domain layer of the Design Model where software classes like Sale gain getTotal(), addLineItem(spec, qty) and navigation. The retail vocabulary survives, so a store manager and a developer can point at the same word "Sale" and mean related-but-distinct things (real-world event vs. software object), lowering the representational gap that makes 1953-style machine-code payroll programs, cited in T1 Ch.9, so hard to modify.
8.2.2 Conceptual Versus Design Class Diagram
Formalize — two artifacts, one notation, different intent
Both diagrams use UML class boxes and association lines, which is exactly why the distinction must be made explicit.
| Dimension | Conceptual (Domain) | Design (Software) |
|---|---|---|
| Subject | Idealized real-world concepts in the domain of interest (POS sale as a real event, a hotel reservation as a real undertaking) | Software classes that will be coded (Java Sale, Reservation with fields and operations) |
| Focus | What exists and how it relates in the world to solve the current problem | How it will be built and will perform — responsibilities as operations, visibility, navigation, patterns, persistence |
| Methods/operations | None. At most a high-level responsibility noted in prose ("Sale handles payment settlement") | Signatures declared, e.g., addLineItem(spec: ProductSpec, qty: int), getTotal(): Money |
| Attributes | Logical data values you must remember (often minimal, sometimes none) | Typed fields, multiplicities, defaults, constraints, derived attributes (/total) |
| Associations | Real-world, need-to-remember connections named in domain phrases; inherently bidirectional in meaning, no navigability | Navigation direction decided, aggregation/composition adornments, ownership, coupling choices |
| Abstraction level | High, conceptual perspective | Specification / implementation perspective |
A simple test: if you showed the conceptual diagram to a domain expert with no software background, they should be able to correct it ("no, a Reservation covers a Stay, not a Room directly"). If you showed the design diagram, they would rightly say "I don't know what private or 0..1 means here."
Analogy — map versus construction plan (professor's analogy, preserved): The domain model is like a map of the territory drawn in everyday street names — it keeps conversation grounded in the names people navigate by. The design model is the construction plan that turns that map into a building — it adds footings, beams, wiring diagrams, and says which walls are load-bearing. You need the first to agree on what neighborhood we are in; you need the second to make it buildable. Critically, the map inspired the plan — the street names survived onto the plan — but the map is not the plan.
Worked example — reading and writing in both directions (lecture exercise)
Direction 1 — Read diagram → five sentences: From the POS domain diagram (Fig. 9.2 / 9.17): 1) A Store houses one or more Registers. 2) A Register captures one current Sale at a time. 3) A Sale contains one or more SalesLineItems. 4) A SalesLineItem records the sale of one ProductDescription (via an Item when tracked individually). 5) A Sale is paid by one Payment (here a CashPayment in iteration 1).
Direction 2 — Text → diagram: Given "A Guest holds a Reservation that covers a Stay; a Stay uses a Room; a Room is typed by RoomType; a Resort has many Rooms" — draw rectangles for Guest, Reservation, Stay, Room, RoomType, Resort and connect them with those verb phrases. The exercise forces the "isolated box" check: if Rate appears as a box but no sentence connects it, either connect it (Stay priced by RatePolicy → Rate) or decide it is an attribute of Stay.
Sense-check: If you can read the diagram aloud to a non-programmer and they can paraphrase the business back correctly, the conceptual perspective is right. If paraphrase requires explaining code terms, you have slipped into design.
Pitfalls
- Treating "has no methods" as "has no behavior." Concepts in a domain model do participate in work — Sale contributes to settlement — but behavior is not yet formalized as operations. Design-by-responsibility will assign behavior later (Larman Ch.17 GRASP). Collapsing this distinction makes analysis feel "just data" and pushes learners back to ER thinking.
- Adding inheritance / aggregation now. These adornments express design commitments. In analysis, keep associations plain and named; let design introduce generalization where an adjective genuinely adds behavior (see 8.6).
Real-world and domain connection: The POS case shows the economic consequence: teams that kept the conceptual and design diagrams as separate artifacts avoided the common trap of building a data model and calling it an OO model — domain collaborations were visible before any choice of database or UI framework was made, so the design could be mapped to Java, C#, or Smalltalk with the same domain layer shape.
8.2.3 Iteration, Scope and Idealized Behavior
Formalize — iterative, scoped, idealized
Three discipline ideas control the domain model's growth:
- Iterative refinement: The domain model is not drawn once. You make a first cut in analysis, refine it in design (adding operations, navigation, patterns), and refine again in implementation — within boundaries. Analysis is where you practice thinking in objects for the first time; later passes make that thinking sharper.
- Scoping: Two boundaries gate every addition: the system boundary (defined during use-case work — what is inside the system vs. an external actor) and the current iteration's scope (which use cases are under design this iteration). A concept outside either boundary is excluded, even if it is a real domain thing. Only enough of the world to represent the current problem completely enters the diagram.
- Idealized behavior: Analysis models what the system should support, not just how work happens today in a manual process. Your solution should be better than the existing way of working. If today's manual resort log conflates "reservation" and "walk-in hold" on sticky notes, the model still distinguishes them cleanly as Reservation vs. Hold concepts because the idealized flow requires it.
Together these say: stay inside the iteration boundary, model the world as it should be to satisfy the requirements, and let understanding grow across passes.
Scope and assumptions
Assumes: UP-style iterative development and a defined system boundary. Applies: each iteration yields a complete model for its stories; later iterations extend, not replace. Breaks if: you try to model the entire enterprise domain up-front (analysis paralysis) or model only "as-is" manual quirks without improving the flow — both violate the UP guideline "avoid a waterfall-mindset big-modeling effort."
Visual intuition: picture a rising staircase of three steps labeled Iteration 1, 2, 3. On Iteration 1's tread sits a small domain model (6–8 boxes) with a dashed boundary labeled "system boundary + iteration scope." Iteration 2's tread shows the same model plus two new boxes added at the edge (e.g., Receipt, Return) and refined lines. The same class names persist, and a small "idealized" badge signals that the model reflects required behavior, not today's handwritten log. Takeaway: growth is incremental and intentional.
Pitfalls
- Expanding beyond iteration scope early because "we might need it for returns later." The model loses focus and the iteration cannot close. Fix: park future ideas on a "next iteration candidates" list, not in the diagram.
- Modeling only "as observed" rather than "as required." Capturing today's double-entry of a booking as two separate concepts entrenches a workaround rather than designing it away.
Q: Is a domain model the same as an ER model? A: No — same lineage, different intent. An ER model captures entities and relationships for data storage: its box is a table-to-be, its line is a foreign-key relationship, and it is judged by storage normalization. A domain model captures concepts that will have behavior and participate in collaborations, even though behavior is not shown yet as methods. At this stage you may note high-level responsibilities, but you do not define operations. The extra idea beyond an entity is purpose and collaboration: a Sale is not just a row in a table; it is a participant that, together with Payment, SaleLineItem and Register, enacts the sale. That is why a domain model cares about collaboration paths, not just columns, and why attributeless classes are acceptable in a domain model but suspicious in an ER model.
Recap + bridge: A useful domain model is iterative (refined across analysis→design→implementation), scoped (system boundary + current iteration), and idealized (models what should be, better than today). With that discipline, the next question is sharpened: given scoped use cases, how do you decide which nouns earn a class and how do you test them? That is 8.3.
Real-world and domain connection: The point-of-sale terminal domain — used throughout Larman's textbook and this course as the running retail example — illustrates the payoff: iteration 1's domain model for cash-only sale is deliberately small; iteration 2 that adds Handle Returns justifies finally adding Receipt (a report object excluded in iteration 1 because its information was derivable, T1 9.9). The model grew only when the stories demanded it, keeping each iteration finishable.
8.3 What Counts as an Object and How to Test It
8.3.1 Anything in the Problem Domain Can Be an Object
Hook: Students often ask for a rule — a single test that says "this noun is an object, that one is not." No such rule exists. What, then, guides the choice?
Formalize — the landscape of candidate origins
There is no formula that maps a noun to a class. Any physical thing, idea, or concept that matters in the problem domain can be treated as an object if it helps solve the current requirement. The question is never "is this kind of noun an object in general?" but "does this concept matter here for solving the current iteration's requirement, with identity, state, and participation?"
Where to look — prompts, not rules — mirrors the conceptual class category list (T1 9.5, Table 9.1):
- Persons and roles: Guest, Customer, Receptionist, Teacher, Dean. Often actors or role-played participants.
- Physical items and tangible devices: Room, Bed, Register, Item, Die, Board, Piece.
- Places: Store, Resort, Campus, City, Airport.
- Transactions and events: Reservation, Sale, Payment, Loan, Flight, MonopolyGame move.
- Catalogs and descriptions: RoomType, ProductCatalog, ProductDescription, FlightDescription.
- Rules, policies, and records: RatePolicy, CancellationRule, Ledger, ReservationLog.
- Supporting / passive receivers: a database or record that never initiates interaction but receives results and retains them (e.g., Ledger that is updated with sale/accounting info, Inventory that is adjusted).
Even "quiet" participants qualify when the domain needs them — a record that only receives a result still remembers information needed for later collaborations. Borderline cases are resolved not by a universal checklist but by domain judgment grounded in the use-case stories for the current scope.
A note on the learning order: many students meet programming first, where objects are already defined, and only later meet analysis where objects must be discovered. That is the reverse of most engineering disciplines, where analysis and design precede implementation. If you have built programs, you can use that memory as a heuristic: ask "would I expect this concept to hold data over time and take part in work, or would it simply be a value held by something else?"
Intuition — stage crew vs. props: Think of a play's script (use cases). Some nouns are cast members (actors, roles) who appear, speak, and remember; some are props with state (a ledger, a ticket); some are scene descriptions that set context but never act. Analysis is casting — deciding, from the script, who genuinely needs a name, a costume, and lines. A prop that is mentioned but never handled on stage may belong as an attribute of whoever carries it, not as a cast member. Break point: unlike theatre, software "props" can gain behavior later via design, so today's prop may be cast in a later iteration when the story demands more from it.
Scope and assumptions
Assumes: the domain is bounded by the current iteration's stories and a system boundary; judgment is exercised within that scope. Applies: analysis can propose broad candidates — filtering comes later via purpose, pruning, and the class-vs-attribute test (8.6). Breaks if: you treat any mentioned noun as automatically a class — that inflates the model and obscures the needed collaborations.
Visual intuition: a scatter of nouns from a use case ("guest", "night", "rate", "city", "campus", "bed", "reservation", "payment") pulled onto index notes. A Venn of three circles — Identity, State, Purpose-for-this-iteration — highlights only the overlapping center as class-worthy. "night" lands outside (a value), "reservation" lands inside (it tracks state across nights, rates, and payments). Takeaway: the filter is overlap, not noun-hood.
Pitfalls
- Checklist memorization. Hunting for a single "object formula" wastes time; Larman and Horstmann both stress that different modelers produce somewhat arbitrary but convergent lists when they apply noun analysis + category prompts + collaboration play rather than a hard rule.
- Ignoring passive but persistent concepts. Dismissing a Ledger or Accounting record because "it doesn't do anything" misses that remembering is doing. If the requirement requires recall, the holder of that memory is a participant.
- Importing implementation bias too early. Labeling something a "database table" now substitutes a storage design for a domain concept.
Real-world and domain connection: In resort booking, persons (guest, receptionist), tangible resources (room, bed), transactions (reservation, stay, payment), and records (guest ledger) all surfaced as candidates; in POS, physical (Register, Item), transactional (Sale, SalesLineItem), and catalog (ProductDescription) ideas do the same work. The search pattern transfers; the domain vocabulary does not.
8.3.2 The Purpose Test
Formalize — one sentence that decides
The most reliable practical test offered in the lecture:
You should be able to state the purpose of the class or object in the problem domain in plain language — one or two sentences saying what this object stands for and what it contributes to solving the current problem.
- Passes: you can write a crisp intension — "A Reservation represents a guest's undertaking to hold one or more rooms over a specific Stay, tracks confirmation status, and initiates assignment and payment." You know its instances (R1, R2, ...), its state (dates, confirmation), and its collaborations.
- Fails: you can only write vague phrasing — "Night is ... a night?" — or describe it solely as a value on another thing ("the night on a date"). If you cannot say what work it does in the story without resorting to "it is a kind of detail," reconsider.
This test does three things at once: (a) rejects invented-but-weightless objects, (b) forces a high-level abstraction anchored in domain language (managing complexity by grouping related information and work under a name people recognize), and (c) enforces that objects own their part of complexity rather than scattering details across functions. Object orientation, in this telling, is a complexity management strategy — each concept hides its interior complexity behind a purposeful name.
Worked example — pass vs. fail
Pass — Student: Representation: the class name Student. Intension: "a person enrolled in the institution who takes courses to earn a degree." Extension: {S1, S2, S3, ... many instances}. Purpose: tracks enrollment status, course load, degree progress; collaborates with Course, Enrollment, Department to enact "register for course" and "graduate" use cases. Many instances, crisp purpose → keep as a class.
Fail — night (as a standalone class): Candidate noun "night" appears in "guest stays for three nights." Try to write its purpose: "A Night represents ... one night?" It has no state beyond a count, no relationships beyond being a value of Stay's duration, and no work beyond being counted. It collapses to a value — an attribute stay.nights or a derived duration — not a collaborator. Keeping it as a class would fragment the model without adding explanatory power.
Sense-check: If replacing the candidate with an attribute on its owner leaves every use-case step still playable, the attribute is the right choice.
Scope — what the test does not promise
Assumes: you are testing within the current domain and iteration — "purpose for this problem." A concept that is decorative in a resort model (e.g., "city" as mere address string) could be a full class in a geographic reservation-search domain. The verdict is context-dependent.
Visual intuition: two side-by-side cards. Card A labeled Student shows a clear box: top line "Purpose: person enrolled ...", middle line "Instances: S1, S2, S3 ...", bottom line "Collaborators: Course, Enrollment". Card B labeled Night shows a dotted box with a question mark under Purpose and a thin arrow pointing to Stay.duration : int. Takeaway: a real purpose anchors instances and collaborators; its absence points to an attribute.
Pitfalls
- Writing a purpose that is just a synonym. "A Client is a person who is a client" restates the name without saying what it does. Replace with the actual role in the story.
- Confusing purpose with implementation. "Student holds a database row" is a storage statement, not a domain purpose.
Real-world and domain connection: Analysts working with Horstmann's voice-mail case use the same test: a Mailbox passes because "a mailbox represents a user's persistent message store, manages greeting and passcode, and queues delivery/retrieval of Messages" — a two-sentence purpose covering state, behavior scope, and collaborations — whereas a transient "dial tone" would not.
8.3.3 Abstraction and Why Objects Help
Formalize — abstraction as disciplined suppression of detail
Abstraction in OOA means keeping the view at a high level and deliberately suppressing implementation detail. You capture enough to see how work gets done (who, with whom, to what end) without deciding how code will do it (which fields, which algorithm, which framework).
Two consequences follow:
- Methods absent by design. The domain model leaves out operations and often shows classes with no attributes yet. You are still deciding what exists, not how it operates internally. That is not incompleteness; it is keeping the abstraction honest.
- Small model, large explanatory power. A handful of well-connected concepts (say, 6–9 classes) can realize many use cases when their associations are right. This is why Larman (T1 Ch.9) celebrates a rich set of conceptual classes discovered quickly — a few hours of skilled modeling often pays off disproportionately in design clarity.
The discipline that keeps abstraction from becoming vague is real-world grounding: associations are named with the domain's own verb phrases ("Reservation covers Stay", "Teacher teaches Student"), vocabulary is held honest in the glossary, and every new concept is tested with "could I explain this to a domain person using their terms?" When that answer is yes, the abstraction is earning its keep.
Intuition — city map at zoom level: Abstraction is like viewing a city map at the zoom level where you see districts and the major roads between them, not the paving texture of each street. That level is sufficient to plan a route across town. Zooming further (implementation detail) before you have chosen which districts matter merely adds noise and invites premature commitment. You can always zoom in later, district by district, iteration by iteration.
Scope — when to deepen
Applies: analysis abstraction holds until design intentionally deepens it — adding operations, visibility, navigation, and patterns. Breaks if: you keep the model abstract into design (no responsibility assignment happens) or you concretize analysis with database or UI detail (bypassing domain reasoning).
Pitfalls
- Collecting attributes speculatively to "prove" abstraction. Adding
student.favoriteColorbecause "it might be useful" violates the need-to-remember principle and confuses completeness with accuracy. - Mistaking few classes for better abstraction. An overly minimal model that collapses Reservation and Stay into one box loses the ability to represent shareable stays, date changes, or partial cancellations — fragmentation exists to make complexity manageable, not merely small.
Q: We tried to identify users and the things affected by responsibilities. We listed people who use services, the responsibilities that affect them, and even quiet databases that only receive results. Does that work? A: Yes — that direction is sound, and it maps directly onto the lenses introduced later in 8.6:
- Users who use services → candidate actors and, on the system edge, boundary ideas (forms, screens) they interact with.
- Responsibilities → work that must be owned by some class; finding a responsibility without an owner surfaces a missing class.
- Things affected even passively → entity ideas that hold persistent information (ledgers, inventories, catalogs) even if they only receive results.
The next step is to apply the purpose test to each candidate: write its purpose in the domain for the current requirement and check that it has instances (not just a one-off datum) and that it will collaborate.
Q: Is past experience the only way to recognize an object? A: Past experience helps a lot — you have seen similar domains and recognize similar shapes — but it is one tool among several, not a gate. The taught sequence is: (1) noun-phrase analysis of use cases as a systematic start, (2) CRC card play to test collaborations, (3) consult past work and category prompts (T1 Table 9.1), (4) prune with explicit reasons, then (5) purpose + scope + instances checks. Experience accelerates each step because you move faster through them, but the steps themselves teach the habit of thinking in objects, which is the real skill to build. Larman and Horstmann both emphasize that working four or five full case studies end-to-end builds this habit faster than reading about it.
Recap + bridge: Anything that matters in the domain can be an object, but earning the status requires identity, state, and a plain-language purpose for the current requirement, kept at a high, real-world-grounded abstraction. With that test in hand, the next section turns the test into a repeatable workshop: mining nouns, walking CRC cards, and using experience without being ruled by it (8.4).
Real-world and domain connection: Horstmann's Voice Mail case (T2 Ch.2) shows abstraction trade-offs concretely: a MessageQueue class appears as a domain-tangible queue abstraction (FIFO) whose implementation (linked list vs. circular array — T2 Ch.3) is deliberately not decided at analysis. Keeping the abstraction at "queue of messages" let the team reason about mailbox behavior without committing to a data structure, illustrating complexity hidden behind a purposeful name.
8.4 Finding Objects — Noun-Phrase Analysis, CRC Cards and Collaborative Thinking
8.4.1 Noun-Phrase Analysis from Use Cases
Hook: Given a two-page resort reservation story, how do you find objects in two minutes without guessing? Underlining nouns turns out to be the fastest disciplined start.
Formalize — textual (noun-phrase) analysis
Also called noun-phrase analysis, natural-language analysis, or Nell's method (after Abbott / Moreno). The idea is intentionally low-tech:
- Read to understand first. Read the use case or problem statement two or three times until you can paraphrase what must be built — do not underline while still confused about the flow.
- Underline nouns and noun phrases. Every noun is a candidate class; every verb / verb phrase hints at a responsibility that may later become an operation, but in analysis you do not turn verbs into methods.
- Collect into a rough candidate list. No filtering while harvesting — the list is possibilities, not answers. Include compound phrases ("product catalog" as one candidate, not two).
- Judge each noun after harvesting. Ask: is this a concept with identity, state, and collaboration for this iteration, or simply a value held by another concept?That judgment cannot be automated — Bus tagging or POS-style automated noun tagging (the lecture's "bus tagging / manual marking") surfaces the same nouns mechanically, but a person must decide "class vs. attribute vs. outside scope."
Judgment uses the purpose test (8.3), the class-vs-attribute test (8.6), and iteration scope. The recommended habit is to avoid selectivity too early: optionally keep two lists — a stronger set you are confident about and a weaker set you are unsure about (might be an attribute, might be vague, might be out-of-scope). Unless you have a strong reason to remove a candidate, keep it. Losing a possible concept now is harder to recover than pruning later. As you continue reading, additional candidates and their attributes emerge.
Worked example — resort reservation, two pages, two minutes on page one (lecture exercise)
Instructor's live instruction: set a timer for two minutes, take pen and paper, underline every noun on page one of the resort reservation case study. What surfaces in that window:
Candidates in under two minutes: Resort, Reservation, Customer, Guest, Room, Bed, City, Campus, Rate, Night, Stay, Payment, Receptionist, Ledger, Inventory, ProductCatalog-like RoomCatalog, Service, Confirmation...
Same method, other domains (portability test):
- Point-of-sale (T1 Case Study, iteration 1 — cash-only sale): nouns Sale, Payment, CashPayment, SalesLineItem, ProductDescription, Item, Register, Store, Ledger, Cashier, Customer.
- ATM system: Account, Card, Branch, Transaction, Receipt, Network.
- Library: Patron, Title, Copy, Loan, Fine, Librarian, Catalog.
- Restaurant booking: Party, Table, Reservation, MenuItem, Order.
The domain changes but the underlining habit is identical. What differs is the keep / drop reasoning after harvesting (pruned in 8.8) — e.g., "Bed" may be a Room attribute if the requirement only counts bed types, not assigns individual beds; "City" may be an attribute of Resort address unless routes or distances are required.
Sense-check: If your page-one list has fewer than ~8 nouns, you were selective too early. The point is breadth-first capture; pruning is a separate step with explicit reasons.
Scope and assumptions
Assumes: usable use-case text exists (fully dressed or at least brief form, T1 Ch.6). Applies: early OOA when you need a fast, auditable starting set that ties directly to requirements text. Breaks if: text is ambiguous synonym soup ("customer" and "client" for the same actor) without a glossary — the noun list then duplicates; synonym resolution (glossary, 8.7) must run alongside. Also known limitation (T1 9.5): natural language is ambiguous — different phrases may name the same class — so mechanical noun-to-class mapping is impossible; categories and collaboration play are needed as cross-checks.
Visual intuition: picture a highlighted use-case paragraph with every noun in yellow. A second panel shows two buckets beneath: STRONG (Reservation, Guest, Room, Stay, Payment — bold nouns that own state and recur) and WEAKER / ATTRIBUTES? (city, night, rate — single-word values whose owner is unclear). An arrow loops from the weaker bucket back into the text with a label "revisit after pruning." Takeaway: capture first, sort second.
Pitfalls
- Turning verbs into methods now. "Guest books Room" does not mean
Guest.book()— maybeReservationSystem.coordinate()orReservation.covers()owns that work. Methods belong to design after GRASP reasoning (T1 Ch.17). - Premature filtering during underlining. Pausing after each noun to judge "keep or drop" slows you down and biases you toward familiar nouns only.
- Tool mystique over judgment. Expecting bus/auto-tagging to decide for you. The tool surfaces; you decide.
Real-world and domain connection: Horstmann (T2 Ch.2–3) and Larman (T1 Ch.9) both open their POS and Voice Mail case studies with this exact step precisely because it is auditable: a reviewer can trace every class on the first domain sketch back to an underlined noun. That traceability makes requirement-to-analysis conversations possible with non-programmers.
8.4.2 CRC Cards and Thinking in Objects
Formalize — Class-Responsibility-Collaborator
A CRC card (Beck & Cunningham, OOPSLA 1989; popularized by Horstmann T2 Ch.2 and Larman via GRASP) is a physical index-card view of one conceptual class. On the card:
- Class: the class name (singular noun, domain term) at the top.
- Responsibilities: one to three high-level pieces of work the class is accountable for in the domain — written in plain language, not as method signatures. Example for
Mailbox: "manage passcode", "manage greeting", "manage new and saved messages." A single responsibility may later give rise to several methods, but at this stage it is intentionally coarse. - Collaborators: other classes it needs to interact with to meet each responsibility. Example:
Mailboxcollaborates withMessageQueueto manage messages;Reservationcollaborates withRoomandGuest.
The workshop practice: lay cards on a table, walk through use cases informally as conversations between cards, and move cards to see who does what. When a responsibility cannot be met alone, the question "who else must be involved?" directly names a collaborator — and thus a missing candidate. The cards are deliberately small (index-card sized) to discourage overloading a single class and are discarded after the session — they are a discovery tool, not archival documentation (T2 2.7).
Intuition — rehearsal with hand props: Think of CRC cards as actors holding cue cards in a rehearsal. Each actor knows their high-level cues (responsibilities) and which other actors they must cue (collaborators). Running a use case is blocking the scene — "Guest arrives" → Receptionist card speaks → Reservation card is created → Reservation cues Room and RatePolicy → Payment cue is triggered. If a line has no one to deliver it, you have found a missing cast member. Like a rehearsal, you rearrange blocking until the scene flows before you write final stage directions (design methods).
Worked example — CRC play for "Leave a Message" / "Book a Resort Room"
Take Horstmann's Voice Mail "Leave a Message" (T2 2.6–2.7) as template — the same play works for resort booking:
Cards on table before play: MailSystem / Mailbox / Message / later MessageQueue.
Play: Caller dials extension → "someone" must locate the mailbox by number. Mailbox cannot do it (it only knows its own number); Message knows nothing about mailboxes. Add MailSystem with responsibility "manage mailboxes" — it collaborates with Mailbox to locate. Once found, MailSystem must deliver Message → delegates to Mailbox manage new and saved messages which collaborates with MessageQueue. Each gap named a new card.
Resort analogue: Guest requests reservation → Reservation card "manage holds over a Stay" needs Room and RoomType; RoomCatalog is discovered when Reservation asks "how do we know which rooms exist and at what rate?" — a collaborator emerges from the conversation, not from noun hunting alone. Cards are moved closer to frequent collaborators, giving a visual cue for coupling.
Sense-check: After playing 2–3 use cases, every important collaboration step should have an owning card and a named collaborator. A responsibility that no card can claim signals a missing concept; a card with no responsibility signals bloat.
Scope — high-level only
Assumes: analysis-level responsibilities only. Applies: discovering ownership and collaboration shape. Breaks if: you write methods on the card ("addMessage(msg: Message): void") — that commits to design signatures before responsibility-assignment reasoning (low coupling/high cohesion) has happened. The lecture repeatedly reinforces: analysis is about what objects exist and roughly what they are responsible for; design-by-responsibility (GRASP, T1 Ch.17) and detailed methods come later.
Pitfalls
- Function-first thinking: defaulting to "the system must book, cancel, validate" and assigning all three to a single
Systemcard creates an omnipotent system class anti-pattern (Horstmann's warning, T2 2.7). Fix: respect natural abstraction layers — system class coordinates; domain objects own domain work. - Mission creep on a card: letting a card accumulate 5–6 responsibilities suggests a hidden cluster; split the card and distribute work.
- Equating responsibilities with methods. A responsibility like "manage passcode" will later become several operations (validate, change, reset) — collapsing them now blocks exploration.
- Magical collaborators. Inventing a "Manager" with no domain name. If you cannot name the collaborator in the domain's language, check with experts before adding it.
Q: What is the full form of CRC cards? A: Class-Responsibility-Collaborator. The card records the class name at the top, its high-level responsibilities in plain language on the left, and the other classes it collaborates with to meet those responsibilities on the right. You use the cards to walk through use cases and see if the current set of objects — talking through their listed collaborations — can do the required work. CRC cards are a technique precisely because they teach thinking in objects — "which concept owns this piece of work and who does it need?" — rather than thinking in isolated functions.
Q: Once we give an object responsibilities, how do we find more objects? A: Follow the collaborators. When a responsibility cannot be met alone, ask "who else must be involved to fulfill it?" That question directly names another candidate object. Keep responsibilities high-level (not methods) at this stage so the discovery remains at the analysis level rather than slipping into coded operations. A student's chat contribution captured this well: once you define an object and give it responsibilities, you discover new objects needed to meet those responsibilities — those new participants are the collaborators, and the loop naturally expands the candidate set until the use-case walkthrough closes without gaps.
Recap + bridge: CRC cards convert noun-list candidates into testable collaborations by assigning high-level responsibilities and exposing collaborators through informal walk-throughs. This collaboration lens connects forward to the intension/extension check — does each collaborator genuinely group similar objects and deserve its name? — which is 8.5, and backward to the pruning step where weak candidates are kept or dropped with reasons.
Real-world and domain connection: Teams in interactive design workshops often prefer CRC cards over diagram tools for early discovery precisely because cards are movable and disposable — the visual proximity of frequent collaborators on the table gives an early, tactile sense of coupling. The practice has been used since Beck & Cunningham's Smalltalk lab to introduce object thinking before formal UML exists.
8.4.3 The Role of Experience and What Happens Without It
Formalize — experience as accelerator, not gate
The lecture is candid: past experience with similar domains and with having built objects before accelerates every step, because you pattern-match faster and recognize when "city" should be a class versus an attribute. Two facts contextualize this:
- Students often meet programming first (objects already given) and analysis later (objects must be found) — the reverse of most engineering where analysis/design precede building. That inversion explains why object discovery feels hard initially even to competent coders.
- Experience is therefore valuable but not the only way to recognize an object, and it is not treated as a prerequisite. The taught fallback sequence when you feel you have "no experience" is exactly the pipeline of this lecture:
- Noun-phrase analysis of use cases as a systematic start.
- CRC play to test collaborations and surface missing participants.
- Category catalog prompts (T1 Table 9.1) to jog overlooked kinds.
- Purpose/intension/extension and class-vs-attribute checks to prune.
- Boundary/control/entity lenses for interaction-heavy domains (8.6).
Applied together, these steps teach thinking in objects; each repetition makes the feel for "keep vs. drop vs. fold into attribute" faster. The lecture explicitly says there is no formula mapping a sentence to a theorem-like answer — judgment develops by doing several cases.
Intuition — learning to taste: Experience in object discovery is like learning to taste wine — no written rule distinguishes a Burgundy from a Bordeaux for a beginner, but repeated guided tasting with prompts (region, tannin, fruit) builds a palate. Noun analysis and CRC cards are those prompts; purpose and scope checks are the tasting notes. After four or five guided tastings (case studies), distinctions that once felt arbitrary become reliably recognizable.
Worked example — disciplined practice plan
The lecture prescribes a hands-on repetition plan rather than more reading: work four or five case studies thoroughly — resort reservation → ATM → library → restaurant booking → POS terminal (Larman) — doing both the noun underlining and the CRC walk-through for each, end to end.
For each case:
- Underline nouns (page-one exercise style), two buckets (strong/weaker).
- Draw a first-cut domain model (5–9 classes, associations in domain verbs).
- Play 2–3 use cases with CRC cards; note where a responsibility asks for a missing collaborator.
- Prune with explicit keep/drop reasons (8.8) and resolve synonyms via a glossary.
Four polished cases beat ten superficial sketches because the same judgments recur (synonym "customer/client," vague "night," tangible "room," catalog "room type," rule "cancellation policy") and the learner's speed and confidence converge. A student's observation is highlighted: once you give an object responsibilities, the collaborators point to the next objects — the practice loop is self-expanding when responsibilities stay high-level.
Sense-check: by case four, you should be able to do a first-cut domain model from a fresh one-page story in under 15 minutes and then defend each keep/drop decision with a one-line reason — that is the observable measure that "thinking in objects" is forming.
Scope and assumptions
Applies: novices through advanced modelers — the same prompts serve both, just faster for the experienced. Breaks if: you skip the workshop and expect a single "right answer list" to memorize. Domain modeling is somewhat arbitrary (T1 Ch.9: "there is no such thing as a 'correct' list") — different skilled modelers converge on similar, not identical, lists, and that is expected.
Pitfalls
- Waiting for experience before starting. Using "I've never modeled this domain" as a reason to delay analysis. The pipeline is designed to work without prior domain experience; expert consultation fills the gap.
- Over-relying on memory of code objects. Importing a previous implementation's class directly ("we had a
DbReservationwith 15 fields last project, so add it now") bypasses the purpose-and-scope checks for this problem.
Recap + bridge: Experience accelerates but does not replace a repeatable workshop — noun analysis → CRC collaboration → category prompts → purpose/attribute/iteration checks. With that workshop internalized, the next step is to tighten the definition of "what counts as a class" using the philosophers' intension/extension lens (8.5).
Real-world and domain connection: Horstmann's Voice Mail walk-through is used as the canonical example where an inexperienced team discovers MailSystem and MessageQueue only through CRC play — not because they recalled the pattern from memory, but because following the collaborator question forced the discovery. The same dynamic recurs in hospitality, banking, and retail case studies across the assigned texts, which is why the course makes doing the cases — not reading about them — the primary learning activity.
8.5 Intension, Extension, Classification and Abstraction
8.5.1 Intension, Extension and Representation
Hook: When does a word on a whiteboard earn the right to become a box with its own name? Philosophers of concepts offer a surprisingly practical three-part test.
Formalize — three ideas behind "does this deserve a class?"
Borrowing the classic analysis of conceptual classes (Larman T1 9.5, after Mordechai & Marcia — symbol / intension / extension), three linked ideas clarify the claim that a candidate is a real class:
- Intension — the definition or purpose — the what and why of the concept in plain words for the problem at hand. If you can define it precisely for the use cases in scope, the intension is crisp. For
Studentthe intension might be: "a person enrolled in the institution who takes courses to earn a degree." It says what counts and why the system must care. - Extension — the set of instances in the real world — the actual examples to which the concept applies, at this moment and over time. For
Studentthat extension is {S1, S2, S3, ...}, many actual students. ForFan,Car,Birdthe extension is also large — many fans, many cars, many birds. - Representation — the symbol or name you use in the model to stand for the concept and carry its definition. The word "Student" in the diagram is the representation that bundles the definition (intension) and denotes the set of examples (extension).
A candidate that has a crisp intension and a real, broad extension (multiple instances) is well-supported as a class: it organizes a genuine plurality under one purposeful name. A concept with a crisp intension but a tiny extension (one or two instances) may be better as a value or anonymous object (see 8.5.2). A concept without a crisp intension cannot be defended as a class regardless of instance count — you cannot explain what it is for the current problem.
These three move together: representation without intension is an empty label; intension without extension is a definition of nothing; extension without intension is an unlabeled pile.
Intuition — dictionary entry: Think of intension / extension / representation as a dictionary entry.
- Representation is the headword in bold ("student").
- Intension is the definition that follows ("a person enrolled ...").
- Extension is every actual student you could point to in the world who fits that definition.
A headword without a definition tells you nothing; a definition without examples is abstract; examples without a headword have no name to reason with. A class-worthy concept is the complete entry that can be used in conversation.
Break point: dictionaries aim for general-purpose definitions; intensions here are problem-specific — "Student" for a bursar's refund system has a narrower intension than "Student" for a learning analytics system, and that narrower scope may change whether it stays a class.
Worked example — Student unpacked (lecture's central illustration)
Consider the concept the lecture calls Student (and the same pattern for Fan, Car, Bird):
- Representation: the class name
Studentas it appears in the domain model box — the symbol the team will use consistently (glossary-backed). - Intension: "a person enrolled in the institution who takes courses to earn a degree." Note the three checks inside the sentence: who (person), what relationship (enrolled, takes courses), toward what end (degree). That sentence survives the purpose test (8.3) verbatim.
- Extension: the set {S1, S2, S3, S4, ...} — all current and future enrolled individuals, a large and populated set. For Fan: {f1, f2, ...}, Car: {c1, c2, ...}, Bird: {b1, b2, ...} — likewise many instances.
Decision: intension crisp and extension broad → keep as a class that groups similar objects. The model gains explanatory power because the class organizes something real (many similar participants) under one definition rather than scattering their information across other boxes.
Counter-sketch: if the problem concerned a bespoke facility with a single bespoke device called "The Main Fan," extension = {that one fan} and intension narrows to "the unique cooling fan of room X." With a singleton extension, a full class adds organizational overhead without grouping benefit — a value-held reference or anonymous object may be simpler (see next subsection).
Sense-check: after writing the intension, try to list three distinct real examples that fit it. If you struggle to find three, the extension may be too narrow for a class in this iteration.
Scope — context-dependent
Assumes: judgment within the current iteration and system boundary (8.2). The same word changes status across problems: "City" as a string-valued attribute of Resort.address (narrow extension per resort) vs. "City" as a rich class with its own districts and transport links in a travel-search domain (broad extension, distinct associations). Intension/extension reasoning is always scoped.
Visual intuition: imagine a Venn of three labeled circles — Symbol (word), Definition (sentence), Examples (dots S1, S2, S3). The intersection at the center is labeled "Class-worthy." An inset shows Fan with many dots spilling out of the Examples circle (broad extension), while "The Main Fan" shows a single dot (narrow extension) pushing the concept out of the center. Takeaway: class-hood is the overlap, and population size matters.
Pitfalls
- Confusing extension with data flow. A student question in the lecture asked whether extension "means moving data from one object to another." It does not. Extension is the set of instances; data flow, if any, belongs to associations and later collaborations — separate concerns.
- Writing intension as a synonym. "A Reservation is a reservation made by a guest" repeats the name without defining purpose, state, or relationships. Replace with the enrollment-like sentence above.
Real-world and domain connection: Larman's Sale as purchase event (T1 Fig. 9.5) is taught with the identical triple — symbol Sale, intension "event of a purchase transaction with a date and time," extension {sale-1, sale-2, sale-3, ...} — to mark the boundary where "Sale" earned a class rather than a string. The same triple test transfers to Flight, Reservation, and Patron, explaining why those catalog concepts repeatedly survive modeling reviews while decorative nouns do not.
8.5.2 When Not to Create a Class
Formalize — narrow extension or no grouping benefit
If a notion has only one or two instances in the problem as scoped, it often does not need a class of its own. The modeling cost (a box, a name, associations to maintain) outweighs the grouping benefit when there is almost nothing to group. In such cases an anonymous object or a simple value (attribute) may be enough.
Horstmann and Larman both use the same contrasting examples to make the judgment concrete:
- Positive — keep:
Fan,Car,Birdwere offered precisely because each has many instances. The class name pays its way by organizing a real plurality (the extension is populous). ACarclass collects shared structure and associations that would otherwise be duplicated. - Negative — fold or drop: a facility's "Main Controller" that exists as a single instance, a one-off configuration string, or the "night" count inside a stay discussed in 8.3 — each adds a box that holds a single value and connects to no one else. Keeping them as classes inflates the model: more names to learn, more lines to maintain, zero additional explanatory power.
This choice interacts with abstraction (8.3.3): at the high level at which you are modeling to manage complexity, each class should pay its way by making the story clearer, not more fragmented. Adding boxes for singleton ideas fragments without clarifying.
A practical rule: if you can replace the candidate by an attribute on its natural owner (e.g., stay.durationNights: int, resort.mainFanMode: String) and still play every use case, prefer the attribute. If you later discover the candidate needs its own state and relationships (e.g., Fan gains speed, requiresMaintenance(), association to Technician), promote it back to a class in a later iteration — the iterative discipline (8.2.3) makes that safe.
Worked example — Student stays, "night" folds
Revisit the Student / night pair from 8.3 through the extension lens:
Student: extension {S1, S2, S3, ... many} → broad; intension crisp → class.Night(as in "stay for three nights"): extension per stay = {1, 2, 3} as counts, not distinct domain participants; intension if forced is "a 24-hour unit of stay duration." No collaborations unique to "a specific night" are required; the stay's duration and dates suffice. Model asStay.nights: intor derivedstay.duration()computed fromcheckIn/checkOutdates (with a date value object, cf. Horstmann'sDay). No class.
Expanding example — singletons vs. populous sets:
- Two bespoke industrial fans in a lab ("Fan A" and "Fan B" that exist only here): extension size 2, intension tied to serial numbers — arguing for a
Fanclass is weaker than in a consumer product catalog whereFanhas thousands of instances and a product description hierarchy. Decision follows scope, not dictionary prestige.
Sense-check: count distinct, concurrently relevant instances demanded by the iteration's stories. One or two → attribute candidate; many and distinguishable → class candidate.
Scope — not about implementation singletons
This guideline is about domain modeling, not about the GoF Singleton pattern or a framework's single instance at runtime. A domain concept may be a singleton in one business (the one Ledger for this store iteration) yet still deserve a class if it holds persistent, audited state and anchors multiple associations (Sale Logged-in Ledger). The extension test is one input; collaboration and persistence also weigh in (see 8.6).
Visual intuition: two bar charts labeled Extension Size. Left chart for Student shows a tall bar (dozens of dots) with label "keep as class." Right chart for "Night-as-class" shows a bar of height 1 attached to a single Stay box with label "fold to attribute." A dashed arrow shows promotion path: if future iteration adds "nightly rate variance by day of week" with distinct rules per night, the bar grows and the arrow lifts the attribute into a StayNight or RateAssignment class. Takeaway: today's attribute can be tomorrow's class when extension and collaboration grow.
Pitfalls
- Premature class inflation to look "object-oriented." More boxes does not mean more OO; it often means more to learn and maintain for no added clarity.
- Treating "has many instances globally" as decisive. What matters is instances in this scoped problem. Globally many "Country" instances do not make Country a class for a single-resort model that only stores it as address text.
Real-world and domain connection: Larman's discussion of when to model Receipt (T1 9.9) uses the same population-and-derivability logic: in iteration 1 Receipt information is derived from Sale + Payment and item returns are out of scope, so Receipt is excluded despite being a domain word with many instances — derivability joined narrow iteration-relevance to exclude it. When the iteration expands to handle returns, Receipt's extension and non-derivable role earn it a class — the same mechanism as the night→attribute decision.
8.5.3 Classification as Grouping Similar Objects
Formalize — classification
Classification is the act of putting similar objects into one class. Instead of treating S1 and S2 as unrelated particulars, you notice they share the same intension (definition/purpose), similar structure (attributes), and similar collaborations, and you place them under the common name Student. The move from objects (many particulars) to class (one concept that stands for all of them) is exactly this grouping.
The same habit clarifies role cases. Consider roles such as Teacher, Student, Dean, Assistant Dean — all are persons, and each role name groups many persons. Whether Role itself should be a separate class or merely an attribute of Person (e.g., person.role: String) depends on whether the role carries additional state or behavior beyond a label:
- Label-only → attribute:
Teacheras a tag onPersonwith no distinct associations or rules beyond "is a teacher" is an attribute value. - Behavior-bearing → class (often via generalization): if
Deanadds approving leave, signing documents, chairing committees — work and associations distinct fromTeacher— thenDeanis better as a class, possibly as a subclass ofPersonor via aRolehierarchy. The lecture notes that adjectives that add behavior hint at this inheritance decision rather than a simple attribute, a point revisited under class-vs-attribute (8.6) and inheritance where the pattern is formalized.
Classification is thus not mere naming; it is organizing work and information by similarity, tested by whether the grouped instances share collaborators, rules, and lifecycle.
Intuition — sorting laundry: Classification is like sorting laundry. You could treat each sock as unrelated, but grouping similar items (all dress shirts, all lab coats) lets you apply one wash rule to the whole group. A role like "lab coat" that merely labels a shirt is an attribute ("tag: lab-coat") attached to the Shirt group; a role like "hazmat suit" that requires distinct handling, associations to decontamination equipment, and a different lifecycle is its own class, even though it is still worn by a person.
Worked example — S1, S2 → Student and the role test
Given instances S1 and S2:
- Observe: both have enrollment id, course list, degree program; both collaborate with
CourseviaEnrollment; both are subject to the same business rule "must be enrolled to register." - Classify: place both under
Student— one definition, one set of associations, one place to state the rule.
Now add Teacher and Dean:
- Enrollment office needs
Deanto approve overloads. That approval is an associationDeanapprovesOverloadRequestwith a policy "Dean approval required if credits > 18."Teacherhas no such association. The presence of a distinct association and rule argues forDeanas a class (or subclass), not aperson.role = "dean"string. By contrast, if "assistant dean" is used only as a display label with no distinct rules or links, it remains a string-valued attribute.
Sense-check: list the associations and rules per role. If two role names differ only in the label string, they are one class with a role attribute. If they differ in links or rules, they differ in class-hood.
Q: What do intension and extension mean for an object idea? A: Use the dictionary picture. Intension is the definition you would write — the purpose that makes this concept matter for the problem ("a person enrolled ..."). Extension is the collection of real instances you could point to, like S1, S2, S3 for Student. Representation is the symbol or class name in the diagram (the word "Student") that stands for both. When someone asked whether extension meant moving data from one object to another, the answer is no — extension is not about data flow; it is the set of examples that belong to the concept. If the extension is large and the intension is crisp, the concept deserves a class; if there are only one or two examples, a direct value or an anonymous object may be simpler. Data flow, when it exists, is carried by associations — a separate concern.
Pitfalls
- Over-classifying roles. Making every adjective ("senior teacher," "visiting dean") a new class creates a fragile hierarchy. Prefer a class when the adjective brings new associations or rules; otherwise keep it as an attribute value and use composition or a type attribute.
Recap + bridge: Intension (definition), extension (example set), and representation (name) together test whether a candidate organizes a genuine plurality; narrow extensions fold to attributes/values, while classification groups similar instances under one name — with distinct behavior pulling a role toward its own class. Those same distinctions sharpen the next operational question: in a concrete candidate list, how do you decide class versus attribute and which catalog prompts help you spot hidden members? That is 8.6.
Real-world and domain connection: In POS (T1 Ch.9) the same triple distinguishes Item (a physical instance with a serial number, many instances in inventory) from ProductDescription (the description of a kind of item — price, itemID, description — shared by many Items). Both earned classes because each has its own intension and broad extension, but conflating them duplicates price info — the Description pattern (T1 9.13) is precisely a deliberate intension/extension split that prevents that duplication.
8.6 Class Versus Attribute and the Common Category Catalog
8.6.1 Telling a Class from an Attribute
Hook: Two nouns appear side by side — "room" and "rate." One becomes a box; the other becomes a number inside a box. What principled choice should you have used, and what fallback when you are genuinely stuck?
Formalize — attribute vs. class
An attribute is a logical data value of an object (Larman T1 9.16) — often simple text or a number with no further structure or behavior of its own and no independent relationships. A class has identity (you can refer to this specific one), can participate in relationships (associations), and may own behavior even if that behavior is not yet shown as methods in the conceptual model.
Practical test (lecture + T1 9.12 guideline):
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).
Concretely, look at each candidate noun and ask:
- Does it need to connect to other concepts via an association that must be remembered? If yes → class. A
Destinationthat is not just a string but a massive thing that occupies space and connects toFlight,Airportservices, andPassengerflows (T1 Fig. 9.22) is a classAirport, not aflight.destination: String. - Does it have its own state beyond a single value — multiple attributes, a lifecycle, rules, or derived information? If yes → class.
- Does it own work or business rules that must be stated against it? If yes → class.
- If it appears only as a simple value held by another concept with no links or rules — e.g., a descriptive string, a count, a date — treat it as an attribute:
room.roomNumber: String,sale.date: Date,salesLineItem.quantity: int.
Tie-breaker rule (lecture, emphasized): When you are genuinely unsure whether something should be a class or an attribute, lean toward class. Analysis aims to find a rich set of objects; keeping a candidate as a class preserves information you can simplify later (fold into an attribute in design when field detail shows it is too thin). Recovering a concept you dropped too early is harder than collapsing a thin class later. This rule interacts with the "do not be selective too early" advice of 8.4/8.8.
Worked example — customer vs. client; city, campus, night, rate
These are the lecture's live borderline calls — each resolved by the "number-or-text in the real world" test and the iteration scope:
- Customer vs. Client (synonyms): Both nouns appear in the resort story. Glossarially they may synonymize, but domain usage picks one as preferred. Keep the term the domain actually uses in speech (say,
Customerif the resort's desk says "customer") and drop the other as redundant (pruning reason, 8.8). Principle: two names for one extension → one class. The other becomes a glossary alias, not a class.
- City: A string in
address.cityin a single-resort system that never reasons about city-level rules → attribute ofResortorCustomerAddress. City becomes a class only if the iteration requires city-level work — e.g., "find resorts by city" with distinct city rules or "compute inter-city travel" with associations toRoute.
- Campus: Same logic. If
campusmerely qualifiesResortlocation as a string value → attribute. If "allocate rooms per campus with campus-specific cancellation policies" introduces rules and associations per campus → classCampuswith associationResorthasCampus.
- Night (as class?): Fails as a class (8.3/8.5) → attribute
stay.nightsor derivedstay.duration()from dates.
- Rate: If
ratenever exceeds "a number on a RateCard" applied uniformly →roomType.rate: Moneyas an attribute. If rate rules grow (seasonal rates, tiered discounts, negotiable corporate rates with approval rules and associations toPricingStrategy,Contract,GuestCategory) → promote toRatePolicy/PricingStrategyclass hierarchy (see T1 Description and Strategy patterns, Ch.31).
Sense-check: Try to draw an association from the candidate to something else. If you cannot name one that the stories require, the attribute form is usually right.
Scope — conceptual modeling only
Assumes: you are in the domain model where types of attributes should not normally be complex domain concepts (Larman 9.16) — e.g., do not model Cashier.currentRegister: Register as an attribute; express Cashier Uses Register as an association. Attribute types are primitive/data types or well-understood value types (Number, String, Date, Money). Breaks if: you encode an association as an attribute to "save a line" — the collaboration is then invisible and CRC play cannot find it.
Visual intuition: a decision diamond labeled "Think of X as number/text in real world?" with two outgoing arrows: YES → rectangle labeled Attribute of Owner (e.g., Sale.date : Date); NO → rectangle labeled Conceptual Class (e.g., Store with its own address, registers, rules). A secondary annotation on the diamond rim: "Unsure? → Class (rich set, fold later)."
Pitfalls
- Definition-wise correct, application-wise wrong. Knowing the definitions but hesitating to apply them. Fix: enumerate the candidate's links and state — that evidence, not the dictionary, decides.
- Attribute as foreign key. Modeling
Sale.customerID: Stringrather thanSalePlaced-byCustomer. The ID is a storage artifact; the domain association is what matters for collaboration reasoning. - Forgetting to justify the borderline. In exam pruning tasks, a bare "make it an attribute" without naming the reason (no state, single value, derivable) loses marks — the reason is the work.
Real-world and domain connection: In the POS case (T1 Fig. 9.22) Larman shows the classic trap explicitly: Cashier.currentRegister as an attribute with type Register is rejected — Cashier Uses Register is the association form. The same reasoning recurs in resort booking: Reservation.guest: Guest as an attribute is wrong; Reservation held for Guest as an association is right, because Guest has its own attributes, history, and collaborations.
8.6.2 The Category Catalog That Helps You See Candidates
Formalize — a checklist of prompts, not rules
Experience can be turned into a checklist of common categories that often map to classes. These are prompts that help you spot candidates you might otherwise miss; they do not force a decision — each match is still filtered by purpose, extension, class-vs-attribute, and iteration scope.
Categories emphasized in the lecture (mapped to Larman T1 Table 9.1's category list for business information systems, with guidance on priority):
- Physical / tangible items:
Room,Building,Device,Board,Piece,Airplane— especially relevant for device-control or simulation domains (Monopoly, telecom switch). Prioritize visible, tracked inventory. - Transactions and transactional events:
Booking,Payment,Sale,Reservation— critical because they involve money/value and anchor many line items, rules, and audit trails. Start here for business systems. - Transaction line items:
SalesLineItem,StayNight(when night-level pricing matters),MealOrderLine— transactions often come with related line items; consider these immediately after the transaction itself. - Products or services related to a transaction/line item:
Item,ProductDescription,RoomType,Flight,Seat,Meal— "the transaction is for something." - Where the transaction is recorded / place of transaction and of service:
Register,Ledger,Store,Resort,Airport,Plane— important to anchor "where is this remembered?" - Roles played by persons and organizations:
Teacher,Student,Dean,Assistant Dean(lecture);Passenger,Pilot,Cashier,Customer,MonopolyPlayer,Airline(T1). Actors in the use case belong here. - Rules, policies, and specifications:
CancellationPolicy,PricingStrategy,DailyPriceChangeList— especially when rules vary by time, contract, or type. - Catalogs and descriptions (description classes, T1 9.13):
RoomCatalog,ProductCatalog,FlightCatalog,ProductDescription— group descriptions of item types distinct from individual physical items/instances. - Containers and groupings:
Store,Bin,Board,Airplane,Resort— things that contain other things. - Other categories (also in T1): Events/incidents with a time/place you must remember, records of finance/work/contracts, financial instruments, schedules/manuals regularly referred to (repair schedule), and collaborating systems / external systems.
Seeing a noun and matching it to one of these buckets gives you a reason to keep it for closer inspection (a prompt to survive early pruning). A lot of physically visible things become classes because you track persistent information about them; some events become classes because they have state and participate in collaborations.
Worked example — catalog prompt catches a hidden class
Scenario: Resort model initially has Room and Reservation. Princeton's rate talk mentions "price calculated from a set of price rules."
Without catalog prompt: Room.price: Money as attribute seems enough — then duplication and update pain surface only later (Larman T1 9.13 — the Item-Descriptor problem: deleting sold Items loses price memory; replicated price across Items is error-prone).
With prompt: "Descriptions of things" and "Catalogs" prompts force the question: is there a description of a type of room (RoomType) with price/amenities/description, distinct from the physical Room (serial-level instance with occupant state), housed in a RoomCatalog? Answer: yes — RoomType (typeID, description, basePrice, amenityList) Describes RoomType? Actually RoomCatalog Describes RoomType, and RoomType itself Types Room (1 to *). ProductDescription plays the same role in POS: one ProductDescription describes many Item instances, so price survives even when Items sell out (ObjectBurger example, T1 Fig. 9.9). The prompt turned an invisible duplication risk into an explicit class before code was written.
Sense-check: after initial noun harvesting, run the category list as a gap scan — for each category, ask "does our model have a member here demanded by the stories?" The missing member is often the most valuable find.
Visual intuition: a circular "prompt wheel" divided into segments — Physical, Transaction, Line Item, Product/Service, Where Recorded, Roles, Place, Event, Catalog/Description, Container, Policy — with the instruction "rotate and ask: does this domain have one demanded by the stories?" Dots on the wheel light up for POS (Transaction → Sale; Product → ProductDescription), and separately for resort (Container → Resort; Description → RoomType). Takeaway: systematic breadth over ad hoc recall.
Pitfalls
- Treating prompts as inheritance templates. A category match is a reason to inspect, not a class declaration. The purpose and class-vs-attribute tests still decide.
- Over-triggering on generic categories. "System" or "Event" as a catch-all class name signals vagueness (pruning reason — see 8.8). Replace with the specific domain name.
Real-world and domain connection: The telecom switch example (T1 9.11) — domain of messages, connections, ports, dialogues, routes, protocols — is the course's reminder that catalog prompts work even for unreal-world domains that lack tangible analogs. High abstraction plus careful listening to expert vocabulary still yields conceptual classes when filtered by purpose.
8.6.3 Boundary, Control and Entity Lenses
Formalize — the ECB (Entity-Boundary-Control) lens
A second, orthogonal grouping lens — prominent in OO design and previewable during analysis — sorts candidates into three kinds by role in a scenario. In UP and in Jacobson/Coad traditions (Horstmann T2 Ch.2 "systems and system interfaces," Larman T1 Ch.14–17 with GRASP):
- **Entity concepts — hold persistent information* that lives longer than a single interaction. They correspond to things you track over time:
Sale,Loan,Reservation,Inventory,Ledger, booking records, room occupancy, passenger manifest. They do the core domain work* and retain state. Lifecycle: long-lived, auditable.
- **Boundary concepts — represent interaction between an actor and the system*. Display forms, login screens, receipt views, confirmation pages, handheld register displays — the surfaces the actor sees and touches* to provide input or see results. They handle presentation and input adaptation, not business rules. Example:
LoginScreen,BookingForm,ReceiptView.
- **Control concepts — manage a scenario and delegate work*. A play-game manager, a booking coordinator, a network-and-security controller, a
ReservationCoordinator— they receive input from boundary ideas and hand coordinated work to* entity ideas that do the persistent core job. They are deliberately lean coordinators, not gods.
Linking the three explicitly (e.g., with links typed as ostom and clc in the teaching diagram — lecture's shorthand) helps the team see that a collaboration path is complete: Actor ↔ Boundary ↔ Control ↔ Entity. A use case that lacks one link often has a gap — e.g., input with no control to delegate, or a control with no entity to retain outcome.
Adjectives and grammar matter operationally (linked explicitly in lecture):
- An adjective that adds behavior ("corporate negotiable reservation") may hint at an inheritance distinction (a subclass or strategy hierarchy) rather than a simple attribute — revisited in inheritance.
- Passive voice hides actors: "the booking was confirmed" hides who confirmed. Turning it into active voice — "the system confirmed the booking" or "the receptionist confirmed the booking" — surfaces the subject noun that may be a missing candidate (often a Control or Actor). Scanning for passive sentences is a concrete pruning/discovery habit.
These lenses are highlighted as within hearing even though full responsibility assignment (GRASP, operation contracts, interaction diagrams) is left to design — they give high-level clarity now and sharpen later assignment.
Intuition — restaurant front-of-house: Think of a restaurant run: the Boundary is the menu and the waitstaff's notepad (what the guest touches); the Control is the maître d' / expeditor who receives orders, sequences them, and hands work to kitchen stations; the Entities are the pantry, the ticket rail, and the table state that persist across the meal. No one expects the menu to cook; the coordination lives in control, the memory in entities, the interaction on the boundary. Missing any one breaks the service path. Break point: in analysis, boundary objects are concepts (the idea of a login interaction), not specific widgets; design will decide the concrete UI classes.
Worked example — login and security (teaching diagram's ostom/clc links)
Flow: Actor (Guest) interacts with LoginScreen (boundary — shows fields, collects credentials), which submits to SecurityControl (control — validates credentials, enforces policy, delegates), which reads/writes CustomerProfile / BookingRecord (entities — persistent account and reservation state).
Associations to draw: Actor —interacts via→ LoginScreen (ostom-type boundary link), LoginScreen —submits to→ SecurityControl (clc-type control link), SecurityControl —coordinates→ BookingRecord / CustomerProfile. If any arrow is missing (e to clc diagram), the collaboration path has a gap spotted instantly by walking the ECB chain.
Passive→active rewrite exercise:
- Passive: "The booking was confirmed and the ledger was updated."
- Active rewrite: "The ReservationCoordinator (control) confirmed the Reservation (entity) and the Ledger (entity) posted the charge."
→ surfaced missing Control (ReservationCoordinator) and made Ledger's entity role explicit — two candidates that passive voice had hidden.
Sense-check: for each use-case step, check you can place it on the Boundary→Control→Entity path. Steps that match none may be out-of-scope or need rewording.
Visual intuition: a left-to-right lane diagram: Actor stick figure on the far left, a vertical "glass wall" labeled Boundary (forms/screens) adjacent, a central hexagon labeled Control (coordinator) with arrows fanning to three persistent cylinders labeled Entity (ledger, inventory, reservation store) on the far right. Links are labeled ostom / clc per the teaching diagram, and each link is drawn as a simple domain-verb line until design adds navigability. Takeaway: path completeness is visual.
Pitfalls
- Letting Control become a god object. A single
SystemControllerthat owns all rules and state defeats the purpose — the control should delegate domain work to entities promptly. Horstmann's warning about omnipotent system classes (T2 2.7) applies here. - Modeling every screen as a permanent class too early. Boundary concepts at analysis level are ideas of interaction, not the final widget hierarchy. Over-committing to widget names locks UI choices before requirements have settled.
Q: How do we decide whether something is a class or an attribute? A: Check whether the thing has only a simple value (plain number or text) with no other behavior or relationships beyond being held. A count, a date-string held by one owner, or a descriptive text that never needs to connect on its own is usually an attribute. If the candidate needs to relate to others (associations), hold its own state (multiple attributes, lifecycle), or own work (business rules, responsibilities that it alone can carry), keep it as a class. When you are genuinely stuck between the two, prefer to keep it as a class at this stage — you can simplify (fold) later in design with more information, but you cannot recover a concept you discarded too early.
Recap + bridge: "Class or attribute?" is answered by the value-vs-participant test plus the lean-toward-class tie-breaker; category prompts and ECB lenses catch candidates that pure noun mining misses (catalog descriptions, policies, collaborating systems, and the boundary/control roles that wire actor input to persistent entities). With the lenses in place, the next discipline is to make the model relational — how associations and a glossary wire the participants together and keep the gap to reality small (8.7), and how a systematic pruning workflow turns the raw list into a finishable model (8.8).
Real-world and domain connection: Boundary/Control/Entity thinking shows up concretely across POS (display forms as boundaries, a ProcessSaleCoordinator or Register as control, Sale/ProductDescription/Ledger as entities), resort booking (booking form → booking coordinator → Reservation/Room/Payment), and airline operations (reservation form → booking controller → Reservation/FlightManifest). The same three boxes and two kinds of links recur, making the pattern a portable analysis sanity check before design adds GRASP responsibility assignment.
8.7 Associations, Glossary and Reducing the Representation Gap
8.7.1 Associations as Real-World Connections
Hook: A page of nouns is not a domain model — it is a word list. What turns a list into a picture of how work actually gets done? Named connections between concepts.
Formalize — what an association is (and is not) at this stage
An association in the domain model is a plain relationship between two classes that reflects how they connect in the real world — for example, a Teacher teaches Students, a Sale Paid-by Payment, a Reservation covers Stay.
Notation and intent in analysis (Larman T1 9.14–9.15):
- Drawn as a simple line between two class boxes, optionally named with the real-world phrase people use — the
ClassName-VerbPhrase-ClassNameformat (Sale Paid-by CashPayment,Stores-*,Houses). The name starts with a capital letter (UML classifier of links); the optional reading-direction small arrow has no model meaning — it only aids reading, and is often omitted. Multiplicity on the ends may be shown where the need-to-remember constraint is clear (e.g.,Sale 1 Contains 1..* SalesLineItem). - Need-to-remember criterion: add an association when knowledge of the relationship needs to be preserved for some duration — milliseconds to years, depending on context. Must we remember which
Reservationcovers whichStayto reconstruct a stay or compute a charge? Must we remember whichSalewasCaptured-onwhichRegisterfor audit? Then the line must be there. Conversely, a transitory look-up (Cashier glancing atProductDescriptions) that leaves no memory need not be an association. - What is excluded now: inheritance, polymorphism, aggregation/composition adornment, navigability direction, and role multiplicity refinements are not added at this stage; those decisions belong to design. At this stage associations are inherently bidirectional in meaning — logical traversal is abstract, not a software navigation claim.
Why identification matters: a domain model without associations is just a list of nouns; with associations it becomes a picture of collaboration — how work moves between participants to achieve a requirement. A practical check: play through a use case and at each step ask "who talks to whom to make this step happen?" If coordination is required and no line exists, a gap exists.
Larman's Common Associations List (T1 Table 9.2) is the companion prompt for finding them — A is a transaction related to B (CashPayment—Sale), is a line item of B (SalesLineItem—Sale), is a product/service for B, is a role related to B, is physical/logical part of B, is contained in/on B, is a description for B, is known/recorded/reported/captured in B, is a member of B, is an organizational subunit of B, uses/manages/owns B, is next to B — run each category against the candidate list as a cross-check.
Intuition — roads on a map, not plumbing: Associations are like roads between neighborhoods on a district map: they say "these two districts are connected and people move this way," named with the actual street name. They are not plumbing diagrams showing pipe direction and valve types — those correspond to design's navigability and aggregation choices. At the analysis map level you only need to know which roads matter and what they are called to explain a journey (use case) across the map. Break point: real roads exist independently of any specific journey; domain associations similarly record need-to-remember connections, not the transient fact that a Cashier once looked at a ProductDescription.
Worked example — naming and gap-finding
Start: simple diagram with Object One —line— Object Two labeled with the domain's common phrase (lecture's introductory association slide). Naming that line "uses" would be weak (T1 guideline: avoid Has / Uses); renaming to covers, assigned to, or hosts adds meaning a domain reader can validate.
Resort example — named associations in domain language: Guest holds Reservation; Reservation covers Stay; Stay uses Room; Resort hosts Guests; Payment settles Reservation; Ledger records Payment. Each name is a phrase a desk clerk would actually say, kept consistent via the glossary.
POS need-to-remember instances (T1 9.15): Sale Paid-by CashPayment, Sale Contains SalesLineItem, SalesLineItem Records-sale-of Item, Sale Logged-in Ledger (so accounting can reconstruct), Register Captured Sale, Store Stocks Item, ProductCatalog Describes ProductDescription.
Gap-finding play: Walk "Guest modifies stay dates." Step requires Reservation to coordinate with Stay (date change) and RatePolicy (re-pricing) and Room (re-assignment). If the diagram has Reservation—Stay but not Stay—RatePolicy, the play stalls at pricing — the missing association is spotted by who-needs-to-talk. Add Stay priced by RatePolicy.
Sense-check: after play, every association should answer "need to remember for how long?" — if the answer is "not at all beyond this instant," the line may not belong.
Scope — parsimony
Applies: a parsimonious set driven by need-to-remember and the Common Associations List. In a graph with n classes, up to n·(n−1)/2 possible lines exist — 190 for 20 classes — and visual noise destroys readability (T1 9.14). Breaks if: you connect everything to everything. Choose the need-to-remember subset; let design add transient navigability.
Visual intuition: a small domain diagram with six gray boxes and five labeled lines connecting them; each line's label sits on the line in a domain verb. Two of the lines are highlighted with caption "transient look-up → not an association." An annotation pointing at a line reads: "named in domain words —Readable by non-programmers— preserves representation gap." Takeaway: few, meaningful, named lines carry the model.
Pitfalls
- Using
Has/Usesas names. They add negligible understanding (T1 guideline). Replace with the domain verb actually spoken. - Confusing analysis association with software navigation. Adding arrows now and arguing about "who navigates to whom" imports design coupling decisions prematurely.
- Leaving associations unnamed. An unlabeled line hides domain reasoning; a domain expert cannot validate it.
Real-world and domain connection: The teaching diagram's ostom/clc links (boundary→control→entity wiring) are exactly need-to-remember associations made visible — without an Interaction line from a control to an entity, the model cannot explain how actor input reaches persistent state, a flaw that design tracing will catch even before code.
8.7.2 The Glossary and Its Role in Keeping Vocabulary Honest
Formalize — the glossary as the model's companion artifact
A glossary (UP Glossary, T1 Fig. 9.1) is the artifact that holds the domain vocabulary: each key concept and significant term is listed with its meaning in the domain's own phrasing — not in code terms. It is built alongside the domain model, and the two are kept consistent.
What it contains:
- For every conceptual class and for significant attributes/association names, the term and its definition (e.g.,
Reservation: "a guest's commitment to hold specified rooms over a dated Stay, with a confirmation status and associated payment undertaking"). - For near-synonyms observed in text (
customervs.clientin the resort story;studentvs.learnerelsewhere), the glossary records one preferred term — the one the domain actually uses — and lists the others as aliases to be dropped from the model. This is the judgment that makes redundancy pruning (8.8) defensible rather than arbitrary. - Attribute requirements implied by the domain model (allowed values, optionality like
middleName : [0..1]) may be transferred to the glossary as the data dictionary companion, because people rarely re-read the diagram for such rules and diagrams are often discarded after iteration (Larman 9.16 guidance).
Habit recommended in the lecture: every time you meet a new term that matters — whether it becomes a class or remains an attribute — define it in the glossary in the domain's own phrasing right then. That entry then anchors later discussion. When you add or rename an association, you can check it against the glossary ("is 'hosts' the verb the resort's staff uses?") rather than guessing what a word meant that week. In artifact terms (T1 Fig. 9.1): use-case concepts + expert insight → domain model ↔ glossary → operation contracts / Design Model / data dictionary.
Intuition — shared dictionary on the wall: Think of the glossary as a shared dictionary pinned to the wall of the modeling room, written in the domain's words, not the team's inventions. Anyone may challenge "what do we mean by 'Reservation' vs. 'Booking'?" and the wall answers. Without it, the same word drifts week to week and two modelers label the same association differently.
Worked example — synonym resolution via glossary
Observation during noun harvesting: Text uses both "customer" and "client" interchangeably when describing the person paying at checkout (resort payment flow, POS).
Without glossary: model accumulates two boxes Customer and Client and two sets of associations — duplication that pollutes CRC play and confuses design assignment.
With glossary habit: Immediately upon seeing the second synonym, capture: Entry: Customer — "person purchasing goods/services at the Point of Sale; the term used at NextGen registers; alias 'client' — not used." The model then keeps one class Customer, aliases noted, association set de-duplicated. A reviewer of the model can now point at the glossary to defend the prune as redundant (8.8) with an auditable reason, not preference.
Sense-check: after each modeling session, scan the model for terms without glossary entries — each such term is a vocabulary risk.
Pitfalls
- Glossary as afterthought. Writing definitions only at iteration end creates inconsistency mid-modeling. Define as you meet the term.
- Definitions in code terms. "Reservation: a BookingRecord row with FK to Guest" buries the domain meaning under storage jargon, reintroducing the gap the glossary exists to close.
Visual intuition: a two-panel picture. Left panel: domain model boxes with labeled lines. Right panel: glossary page with bolded terms and plain definitions. A double-headed arrow labeled "kept in sync" connects them, with a sticky note on the arrow reading "synonym? → pick preferred term." Takeaway: the model shows structure; the glossary holds meaning, and each keeps the other honest.
Real-world and domain connection: The NextGen POS Glossary (T1 Fig. 9.1) is the textbook's illustration of this linkage — elaborating "Sale," "Payment," "ProductDescription" in plain retail language so that operation contracts and the Design Model can cite those definitions rather than re-inventing them. Teams that maintain a glossary report fewer renaming arguments and cleaner design reviews because vocabulary disputes are resolved once, against the glossary, rather than relitigated per diagram.
8.7.3 Closing the Representation Gap
Formalize — representation gap and the domain-language lever
The representation gap is the distance between how the real world describes a problem and how software describes it. The larger the gap, the more translation — and misunderstanding — sits between a domain stakeholder's mental model and the software model.
In older function-oriented work using C-like languages, that gap was large: real-world things were encoded as functions and record structs with names far from everyday speech (Larman T1 9.3, Fig. 9.6: the 1953 payroll program as 1000010101... as the extreme gap). Someone looking at that encoding cannot see the payroll domain; each change requires re-translating domain intent into procedural form.
Object-oriented analysis aims to shrink that gap by using the same terms in the analysis model that people use in the world — class names, attribute names, and association verb phrases drawn directly from domain speech. That is why every guideline so far converges here:
- Class names are domain nouns (Sale, Reservation, Payment, Guest) rather than technical labels (TxnManager, DataStore).
- Association names are domain verbs (
hosts,covers,is assigned to,settles) rather than generichas/usesor storage labels (FK_Reservation_Room). - Domain model is a conceptual-perspective model that inspires — but is not identical to — the software classes of the Design Model's domain layer. In the design layer, the object-oriented developer takes inspiration from real-world names (domain Payment → software
PaymentwithgetBalance(): Money) so the software representation and the mental model stay low-gap (T1 Fig. 9.6).
The gap is never zero — software must still make implementation choices (visibility, navigation, persistence) that the domain does not — but reducing naming and conceptual distance has a practical time-and-money consequence: comprehension and modification become cheaper because reviewers and domain experts remain able to read and correct the model.
Intuition — translation tax: Imagine two teams describing a bridge booking to a clerk. Team A says "function processBooking(R) updates struct B001 and calls calcRate()." Team B says "Reservation covers Stay; Stay uses Room; RatePolicy prices Stay." The clerk can correct Team B ("in our resort, a reservation can split across two room types for one stay — add StaySegment"), but cannot correct Team A without a translator. The gap is a translation tax paid on every requirements conversation and every change; domain-named associations reduce that tax.
Worked example — verbs that shrink the gap (lecture's phrasing)
Compare generic vs. domain naming on the same links:
- Weak (larger gap): Resort —
has→ Guest; Guest —has→ Reservation; Reservation —has→ Room. - Strong (smaller gap): Resort hosts Guests; Guest holds Reservation; Reservation covers Stay; Room is assigned to Reservation.
The second set can be read aloud to a desk clerk who can immediately say which is inaccurate for this resort (maybe in this resort Stay is the human story and Reservation is the system promise — fine, the glossary should record that distinction). The first set carries zero domain checkability.
POS illustration (T1 Fig. 9.6): The stakeholder's view conceptual Payment (amount) —Pays-for→ Sale (date, time) directly inspires the design's software Payment (amount: Money) :: getBalance(): Money and Sale (date: Date, startTime: Time) :: getTotal(): Money. Same nouns survive; added detail is typed and operational but the names remain recognizable, so a store manager and a developer can point at "Sale" and mean related-but-distinct things while understanding each other.
Sense-check: ask a domain person to paraphrase each association aloud. If they naturally use the same verb you wrote, the gap is small; if they rephrase with a different verb, adopt theirs — that is now the association name.
Scope — where alignment helps and where it must break
Applies: comprehension and stakeholder validation — the primary intended audience of the domain model is people, and domain language keeps them in the loop. Breaks/limits if: you stretch domain naming to cover purely technical concepts that have no counterpart in the domain (e.g., a TransactionManager or ConnectionPool — model those only in design). Also past programming experience helps here: teams that have maintained systems where gap was large learn to value alignment more quickly and so invent fewer technical synonyms.
Pitfalls
- Inventing clever technical association names (
aggregates,composes,holdsReferenceTo) that encode design adornment prematurely. Keep verbs in the domain's everyday speech. - Normalizing verbs to a single canonical set across the organization (mandating
hasfor every association). Uniformity is useful; uniformity that erases domain meaning is worse.
Q: What is the difference between an association and a relationship? A: For analysis purposes they are the same idea: a plain, real-world connection that says two concepts are related and may need to talk to do their work — e.g., Teacher teaches Students. Analysis uses the simple form of association: a line between two class boxes named with real-world words that indicates logical connection, not implementation. Richer kinds of relationship — inheritance (is-a), aggregation/composition (whole/part adornments), polymorphism, navigability, typed roles — are analysis-level distinctions left for later when the model needs that precision in the Design Model. So when the lecture says "association vs. relationship" are the same, it means the plain conceptual link; design refines relationships into several specialized forms.
Recap + bridge: Need-to-remember, domain-verb associations wire participants into testable collaborations; a living glossary keeps each term honest and resolves synonyms; together they shrink the representation gap so stakeholders and modelers talk in one language. With those wiring and vocabulary tools in place, the remaining work is turning a harvested candidate list into a finishable, pruned model iteration by iteration — the walkthrough of 8.8.
Real-world and domain connection: In resort reservations ("hosts guests," "reservation covers stay"), retail POS ("sale paid-by payment," "sale contains line items"), airport check-in ("flight flies-to airport"), and telecom switching (message routes via connection), the association vocabulary differs but the gap-shrinking move is identical: keep the diagram's words as the words the domain's people already use, and let those words become the software's domain layer names. The resulting models are readable without translation and traceable from glossary through design to code.
8.8 From Candidate List to Refined Model — Pruning, Iterations and Case Studies
8.8.1 Building and Pruning the Candidate List
Hook: You underlined thirty nouns. Now you must draw a diagram that fits on one whiteboard. Which nouns stay, which fold into attributes, and which vanish — and how do you justify the call so a reviewer can follow it?
Formalize — seven-step workflow from raw candidates to light class diagram
The lecture ties all prior lenses into a concrete, repeatable workflow (the same flow underlying Larman T1 Ch.9–10 for moving requirements → domain model → SSD/contracts):
- Start textual analysis on the use cases. Underline every noun / noun phrase and collect them into a rough candidate list. Include all that appear; do not filter while gathering. The list is possibilities, not answers. Optionally run Bus/auto tagging to check manual capture — but keep judgment manual.
- Optionally tag / Bus-tag the text. Use automated noun surfacing as a completeness check, not a decision-maker. Merge tagged results into your rough list.
- Build two working lists. Keep a stronger set you are confident about and a weaker set you are unsure about (might be an attribute, vague, decorative, or outside scope). Calling them strong and weak, or vehicles for consideration, keeps weaker ideas visible rather than hiding them prematurely. That two-list habit is presented as the primary safeguard against losing information under time pressure.
- *Evaluate each candidate with a strong reason to keep or drop.* Pruning reasons taught (lecture + T1 guidance) — use them as audit labels:
- Redundant — two or three nouns mean the same thing (customer = client; reservation = booking in this domain's speech) → keep the term the domain actually uses, drop the rest as aliases in the glossary.
- Irrelevant — noun sits only in narrative color and has nothing to do with the requirement being solved.
- Vague / ill-defined — high-level phrase you cannot picture as an object with state, behavior, and identity (e.g., "system" as a generic manager, "data" as a substance).
- Attribute — simple text/number that belongs as a feature of another concept rather than its own concept (
sale.date,stay.nights,room.roomNumber). Apply the class-vs-attribute test (8.6). - Operation — a verb-like idea that describes work but not a durable participant ("booking" as the act of booking vs.
Reservationthe undertaking). Operations become responsibilities, not classes. - Out of scope — concept outside the system boundary set in use-case scoping (8.2) — real but not our problem this iteration.
- Additional checks:
- An incident or event that does have state, behavior and identity (e.g.,
Sale,Payment,GameMove) can stay as an object even though it is an event. - A role that adds behavior may stay as a class/distinct type rather than a mere label.
- An adjective that merely qualifies a value stays as part of an attribute (
roomType = "deluxe"); an adjective that adds behavior / distinct rules may hint at a separate class or inheritance later ("corporate negotiable reservation" with distinct pricing rules →NegotiableReservationspecialization). - Passive voice surfaces hidden subjects — turning "the booking was confirmed" into active voice ("the Receptionist confirmed the booking" / "the System confirmed the booking") names a candidate actor/control that passive phrasing hid.
- When you drop an item, you need a strong reason; when you keep one, you need positive evidence. Evidence for keeping: the candidate carries state + behavior + identity, participates in relationships (associations you can name), or groups many instances (broad extension). If unsure between attribute and class, the tie-breaker from 8.6 applies: keep it as a class for now — you can fold it in design; recovering a dropped concept is harder.
- Add known attributes to the remaining classes and sketch associations between them using real-world phrases. Keep the result as a light class diagram — a high-level picture with at most a few attributes per box, plain named associations, no methods — that together with the glossary shows the current understanding. Use the need-to-remember association criterion and the Common Associations List (8.7) as a completeness check.
- Test the set against use cases with CRC-style play. Walk 2–3 stories: can these objects, talking through their associations, realize the required flows? Missing participants or missing links show up immediately as play stalls. Adjust and re-prune.
An active-voice habit helps during pruning (turn passive sentences into active ones to surface hidden subjects), and scanning for adjectives that carry behavior surfaces inheritance hints without yet committing to design detail.
Worked example — strong / weak lists and pruning labels in practice
Start — raw candidates from two-page resort story after noun harvesting + tagging: {Resort, Reservation, Customer, Client, Room, Bed, City, Campus, Night, Rate, Stay, Payment, Receptionist, System, Data, Inventory, Ledger, PriceRule, Confirmation, Booking} (~20 items).
Split into working lists:
- Strong (clear purpose, broad extension, collaborates):
Resort,Guest(canonical for Customer/Client — see below),Reservation,Stay,Room,RoomType(catalog),Payment,Receptionist/FrontDesk(actor/role),Ledger(persistent record) — 8–9 items. - Weaker (needs decision):
City,Campus,Night,Rate,Bed,Inventory,System,Data,Confirmation,Booking(synonym of Reservation?).
Pruning pass with reasons (exam-style justification — the reason is the work):
Client→ redundant withCustomer; domain says "guest" at desk, so keepGuest, dropClientas glossary alias.Night→ attribute ofStay— plain count/duration, no independent links beyondStaydates.Booking→ redundant withReservationin this resort's speech — keepReservation, aliasBooking.Data→ vague/ill-defined — cannot picture state/behavior/identity.System(as lone class) → vague — generic manager; real responsibility belongs to scoped coordinators (ReservationCoordinator) discovered via control lens, not a catch-all.City/Campus→ scope-dependent: for single-resort booking that merely records address, attribute ofResort.address; if the use case required "search by city/campus" with distinct rules, they would be promoted to class.
Evidence for keeps:
Roomkeeps — has state (status,roomNumber), participates inRoomassigned toReservation, groups many instances, distinct fromRoomType.Reservationkeeps — carries state (dates, confirmation status), participates inGuestholdsReservationcoversStay, payment, ledger.- Incident
Paymentkeeps — even though it is an event, it has amount, method, time, and settlesReservationwith audit need.
Result: add attributes (Reservation.confirmationId, Stay.checkIn/checkOut, Room.roomNumber, Payment.amount / method), then draw plain associations in domain verbs (Guest—holds—Reservation—covers—Stay—uses—Room; Reservation—settled by—Payment). Walk "guest books room for three nights, pays" with CRC cards to check the play closes without gaps.
Sense-check: the light diagram that results fits on one whiteboard, each surviving box can answer "what is my purpose in one sentence?" and every pruned item carries a one-line strong reason tag a reviewer can audit.
Scope — when this workflow applies
Assumes: current-iteration scope and a defined system boundary from use-case work. Applies: any information-system domain where stories exist as text. Breaks if: you prune before you have read the story 2–3 times to understand what is required — premature judgment drops context you had not yet recognized. The lecture is explicit: do not be selective early; only remove an item when you can state a strong reason.
Visual intuition: a left-to-right pipeline picture — a tall stack of nouns (raw list) feeds through a funnel labeled "Strong vs. Weak (2 lists)" then through a filter wall with six labeled doors (Redundant, Irrelevant, Vague, Attribute, Operation, Out of Scope). Candidates either pass through to boxes on the right (light class diagram with named lines) or fall into labeled bins. An active-voice arrow curves back from the filter to the raw stack with caption "passive → active surfaces hidden subject." Takeaway: breadth first, reasons-tagged filtering, visual audit trail.
Pitfalls
- Pruning on gut feel without a named reason. "Night doesn't feel like a class" would be marked vague in an exam; "night has no state beyond a count held by Stay and no relationships → attribute" is the auditable answer.
- Carrying synonyms as separate classes. Customer and client as two boxes doubles associations and later design work; resolve via glossary once, carry once.
- Reducing an event to an operation.
Paymentas a verb "to pay" (operation) rather than as a persistent undertaking with amount/method/audit role misplaces the work that survives the interaction and must be remembered.
Real-world and domain connection: The POS case (T1 Ch.9) uses exactly this traceability — every domain class on the first model (Sale, CashPayment, SalesLineItem, ProductDescription, Item, Register, Store, Ledger, Cashier, Customer) is traceable to an underlined noun, and each excluded idea (e.g., Receipt in iteration 1) is excluded for a stated reason (derived/duplicate until returns arrive), so a reviewer can verify scope decisions rather than relitigate taste.
8.8.2 Learning by Doing — Case Studies and Iteration Discipline
Hook: Reading about objects does not teach you to see them. What practice volume actually moves the needle — and what hands-on routine makes that practice stick?
Formalize — case-study discipline and iteration discipline
The lecture turns the workflow into a practice prescription and an iteration ethic that together replace "read more theory."
Practice prescription — 4-to-5 full cases, hands-on:
The central exercise uses a resort reservation system case study that spans two pages of narrative, but parallel quick studies are named for an ATM system, a library system, and a restaurant booking system, alongside Larman's point-of-sale terminal running example. The instruction is tactile — take pen and paper; read the two-page story at least two or three times to grasp what must be built; draw a light activity/Data Flow view by hand to see inputs and outputs; underline every noun; extract candidates; group similar objects into classes; reason explicitly about which candidates should become attributes or disappear as redundant or irrelevant.
The discipline advice is quality over quantity: solve at least four or five complete cases end-to-end — analysis through design to programming — rather than many partial sketches. Four polished, fully reasoned cases teach more than many thin ones because the same judgments recur (synonym customer vs. client; whether campus / city should be a class; whether rate / night should be a class or a value; how an event with state earns a class) and the learner's feel for when a noun should stay, become an attribute, or go becomes faster and better grounded. The lecture is blunt: no amount of reading substitutes for that hands-on repetition.
Iteration discipline — two guardrails that run through every case:
- *Do not rush to name every future object at once. Make a first cut that is complete for the current iteration's requirements, then refine across analysis → design → implementation as understanding grows. The first cut made in analysis is where you practice thinking in objects*; later passes make that thinking sharper. Early big-modeling that attempts completeness for imagined futures is labeled analysis paralysis (T1 9.4) — it will never be truly correct nor repay the time.
- Always constrain within the current iteration's requirements and its system boundary. Expanding beyond that scope early makes the model hard to finish and hides the idealized behavior you are trying to capture — what the system should do well, not just what happens manually today. The result should be better than the existing manual workaround, not a transcription of it.
Together these say: finish a coherent iteration, auditably reasoned, then build on it.
Worked example — hands-on routine for one case (resort), repeated across five
Hands-on routine — resort (2 pages):
- Read pages 1–2 twice, write a one-sentence goal: "Let a guest hold a reservation that covers a dated stay using rooms, priced by a policy, and settle it with payment."
- Two-minute noun-underlining drill on page 1 (8.4), then harvest page 2. Collect ~20 candidates.
- Hand-draw a light activity flow (guest request → check availability → price → record hold → payment → confirmation) and a minimal DFD of inputs/outputs — not to keep, but to see inputs and outputs and to catch missing associations.
- Split into strong / weak lists; prune with explicit tags (redundant, vague, attribute, operation, out of scope); promote city/campus/rate/night only if the story demands city-level search or night-level variance.
- Add attributes + plain domain-verb associations; draw the light class diagram (target 6–9 boxes) + glossary entry per term.
- CRC play 2–3 use cases ("new booking," "modify dates," "cancel"); adjust gaps.
Repeat with domain shift:
- ATM: nouns Account, Card, Transaction, Branch, Limit, PIN, Network → prune e.g., "branch" attribute vs. class depending on whether branch-specific rules exist for this iteration.
- Library: Title vs. Copy vs. Loan — catalog prompt forces
BookDescriptionvs.BookCopysplit (Larman T1 9.13) analogous toRoomTypevs.Room. - Restaurant: Table, Reservation, PartySize, MenuItem; "night" has no analogue, but
Table.statusvs.Tableas assignment entity recurs. - POS: Larman's iteration 1 cash-only Process Sale so the model stays small; Receipt excluded until Handle Returns arrives — iteration scoping exercised.
Exam-prep tie-in: for domain-model exercises, be ready to read a diagram and write five clear sentences explaining the concepts and how the objects interact, and conversely build a diagram from a textual problem; for pruning exercises, be prepared to justify each keep/drop candidate with a strong reason and to handle synonyms by picking the term the domain actually uses.
Sense-check: after five cases you should be able to, from a fresh one-page story, produce in <20 minutes an audited pruned list + 6–9 box domain diagram + five-sentence read-back that a domain peer can correct — that is the practical measure of iteration discipline.
Visual intuition: a five-panel comic strip — panels 1–5 each show a different domain picture (resort ledger, ATM keypad, library shelf, restaurant table plan, POS register) but all share the same underlying five-step workflow icons (underline, group, prune with reasons, associate, walk the stories). A banner across the top reads "discipline, not domain." Takeaway: the practice transfers because the exercise shape is invariant.
Pitfalls
- Many thin cases instead of few polished ones. Breadth without depth does not build the feel for borderline calls; it rehearses only noun hunting.
- Expanding scope mid-iteration because a teammate says "and later we will need X." Park X on the next-iteration candidates list; keep the current diagram finishable.
- Transcribing "as-is" manual quirks (sticky-note holds for reservation and walk-in fused) instead of modeling idealized behavior (distinct Reservation vs. Hold with proper rules). Your solution should improve on today's process.
Real-world and domain connection: Across retail, hospitality, banking, catalog, and service domains the same exercise shape — underline, group, prune with reasons, associate, walk the stories — recurs verbatim, which is why Horstmann (T2) and Larman (T1) both anchor entire textbook chapters to repeating the POS and Voice Mail cases end-to-end. The practical payoff highlighted in industry retrospectives is team-level: after four or five shared cases, vocabulary and pruning reasons become a common language, and new feature discussions converge faster.
Q: Under time pressure how do we avoid dropping a good candidate by mistake? A: Use the two-list safeguard: keep a visible strong and a weaker set rather than discarding uncertain candidates immediately. Only remove an item when you can state a strong reason — redundancy, irrelevance, vagueness, being a simple attribute value, being an operation rather than a participant, or being outside the system boundary. That way you preserve information and can promote a weak candidate later when new relationships show it is needed (e.g., Rate as attribute becoming RatePolicy once pricing rules appear). The lecture presents this as the direct antidote to premature selectivity — unless you have a strong reason to remove, keep it.
8.8.3 Attributes, Roles and the Next Phase
Formalize — settled state before moving to design
By the time the candidate list has been pruned, each surviving class should have:
- a short, plain purpose statement (intension) —
- a sense of whether it groups many instances (extension) and any known attributes that are simple values, and
- any associations in domain language that wire it to collaborators.
The surviving set is naturally viewed through the entity / boundary / control lenses (preview from 8.6, foreshadowing design):
- **Entity ideas that retain persistent information** remain central:
Reservation,Stay,Roomoccupancy,Sale,Loan, booking records,Ledger. They live longer than any single interaction and do the domain's persistent core work. - **Boundary ideas that sit on the actor–system edge** hold the interaction: login screens, booking forms, display views, receipt views — the surfaces actors touch to provide input or see results.
- **Control ideas that coordinate work* sit between them: a BookingCoordinator / PlayGameManager / Network-and-Security Controller that receives input from boundary ideas and hands work to entity ideas. Login screens as a boundary where the actor interacts, the Security Control as the coordinator that receives that input, and the underlying profile/booking data as entities* that retain state — the lecture's login→security→data chain — is the canonical ECB wiring.
The lecture also marks two transition notes:
- What was covered so far in analysis proper: classes, associations, and attributes — the vocabulary and wiring that lets the domain be talked about completely for this iteration.
- What comes next: the last part of analysis after the domain model is system contracts (in Larman's UP sequence — Ch.11 / SSDs + contracts extending from use cases and the domain model), followed by movement into object-oriented design where responsibilities become detailed, methods appear, and GRASP assignment, interaction diagrams, and visibility/navigation choices are made.
The classes to carry forward are intentionally limited — the lecture explicitly notes that today it built the ninth class concept precisely to make the next design step manageable. That pacing is itself an iteration lesson: finish a coherent cut, then build on it; do not carry a bloated analysis into design and hope design will sort it out.
Visual intuition: three stacked horizontal bands — top band Boundary (login form, booking view icons on the actor edge), middle band Control (one or two coordinator hexagons), bottom band Entity (several persistent cylinders: Reservation, Room, Ledger, Sale). Associations run as thin lines across bands, with a callout noting "today: 9 classes carried forward — lean enough to design." Takeaway: lean analysis, clear lanes, design-ready.
Pitfalls
- Carrying a bloated analysis into design. Every vague or undifferentiated class carried forward multiplies design decisions and interaction diagrams. Prune in analysis while reasoning is cheap.
- Neglecting to state purpose for each carried class. Without a one-sentence purpose, design cannot assign responsibilities coherently — ownership debates replace analysis.
Recap + bridge — and the forward handoff: The pruned, purpose-anchored set — with attributes as simple values, associations as need-to-remember domain verbs, and entities / boundaries / controls as previewed roles — forms a complete, lean picture for the current iteration. In Larman's UP flow that picture next feeds system contracts (the analysis close-out), and then design deepens it: the same named classes gain responsibilities as operations, and interaction and visibility choices make the collaboration buildable. Keeping the carried set to nine this iteration was intentional — small enough to reason about, complete enough to teach the discipline that scope, purpose, and pruning reasons must stay together when the work moves to the design room.
Real-world and domain connection: In POS (T1 Ch.9→11) the lean domain model (Sale, Payment, ProductDescription, etc.) feeds directly into System Sequence Diagrams and Operation Contracts — the formal analysis exit — before GRASP-driven design assigns who does what. Resort, ATM, library, and restaurant cases follow the same exit ramp: contracts state postconditions on the domain objects, so the design discussion starts from already-agreed vocabulary rather than fresh invention. That continuity is the practical payoff of keeping the carried set lean and well-defined here.
Exam Guidance Summary
No exam-specific mark distribution, question format or chapter focus was stated in this session. The study advice given was practical and process-oriented.
Exam note — what to actually practice:
- Core skill: use-case writing (T1 Ch.6) — the course treats it as a repeatable, assessable skill that feeds everything downstream.
- Domain modeling drill: be ready to read a diagram and write five clear sentences explaining the concepts and how the objects interact, and conversely build a diagram from a textual problem — both directions strengthen the word↔structure link and that two-way exercise is explicitly named as exam-relevant.
- Pruning drill: be prepared to justify keeping or dropping any candidate with a strong reason — redundant, irrelevant, vague/ill-defined, attribute, operation, out of scope (plus event-with-state, role-with-behavior, adjective-with-behavior checks) — and to handle synonyms (e.g., customer vs. client) by choosing the term the domain actually uses (glossary-backed).
- Hands-on cases: practice noun-phrase analysis + CRC play on at least four or five full case studies — resort reservation, ATM, library, restaurant booking, and the point-of-sale terminal from Larman's textbook — end-to-end rather than skimming many partial sketches; four polished cases build the judgment that a single thin case does not.
- Companion habits: keep a glossary of domain terms alongside each model; stay within the current iteration's scope and the system boundary; ensure every class has a plain purpose statement (intension) — vague purpose is treated as a reason to reconsider.
- Associations: name them in domain verbs, use the need-to-remember criterion, and expect to explain why a plain line suffices now and where inheritance/aggregation would be added only in design.
Real-world carry-through: the same checklist — purpose per class, reason-tagged prune, glossary-backed synonym choice, need-to-remember associations, lean carry-forward set — is exactly what a design review checks before contracts and GRASP assignment, so exam practice mirrors professional gate practice.
Key Industry Applications
The same identification and pruning discipline — underlining nouns from use cases → building a raw candidate list → splitting strong/weak → pruning with explicit reasons (redundant, irrelevant, vague, attribute, operation, out of scope) → deciding class vs. attribute → adding associations in domain verbs (need-to-remember) → applying entity / boundary / control lenses → walking CRC collaborations → keeping a glossary → scoping to the current iteration — was illustrated across five transferable cases that together cover retail, hospitality, banking, catalog and service domains:
- Resort reservation system — the two-page noun-phrase case study that anchors the lecture: guests, rooms, stays, rates, payments, ledgers, and the borderline calls (city, campus, night, rate, customer vs. client) that exercise every prune reason and the class-vs-attribute tie-breaker. Used as the live two-minute underlining exercise and the light activity/DFD sketch that surfaces inputs and outputs.
- Point-of-sale terminal (NextGen POS, Larman T1 Ch.3–9) — the course's running retail domain model (Sale, Payment, SalesLineItem, ProductDescription, Item, Register, Store, Ledger, Cashier, Customer) and the canonical example of Receipt as a report object excluded in iteration 1 because it is derivable and out-of-scope for cash-only sale, then justifiably included when Handle Returns enters scope — iteration discipline made concrete. Also the example of
ProductDescription/Itemas a description-class split that prevents price duplication (Larman T1 9.13). - ATM system, library system, restaurant booking system — suggested parallel practice cases for end-to-end analysis → design → programming at small-team scale. Each replays the same shape with different nouns (ATM: accounts, cards, transactions, branches; Library: titles, copies, patrons, loans, fines; Restaurant: tables, parties, reservations, menus) so that synonym handling, event-as-class, role-vs-attribute, and catalog/description spotting get repeated until judgment is fluent.
Combined with activity-diagram flow views (to see inputs/outputs and sequence) alongside the conceptual class diagram (to see participants and collaborations), and a maintained glossary (to keep vocabulary honest and resolve synonyms once), the steps show how abstract analysis choices — which nouns earn a box, which collapse to an attribute, which line needs to be remembered and named in the domain's words — translate into a software structure that stays close to real-world vocabulary (small representation gap) and feeds cleanly into system contracts, GRASP responsibility assignment, and the domain layer of the Design Model. That close vocabulary is the practical bridge from analysis to buildable design across domains.
OODAP Lecture 8 notes · Object-Oriented Analysis and the Domain Model
Sections Breakdown
OOA after SIS/use cases decomposes the domain into collaborating objects with shared vocabulary, contrasting object vs functional decomposition and the C-requirement/D-requirement view.
Domain model as visual dictionary of conceptual classes, attributes and need-to-remember associations without methods, distinct from design class diagram, scoped iteratively with idealized behavior.
No formula for objects; broad candidate origins and the purpose test plus high-level abstraction explain why objects manage complexity.
Noun-phrase underlining of use cases, CRC (Class-Responsibility-Collaborator) walk-throughs, and experience-accelerated collaborative thinking as repeatable discovery workshop.
Intension/extension/representation triple and classification grouping test; narrow extensions fold to attributes; role behavior decides class vs attribute.
Attribute vs class test (number/text in real world), category catalog prompts, and Entity-Boundary-Control lenses with active-voice and adjective heuristics.
Need-to-remember associations named in domain verbs, glossary as vocabulary companion, and shrinking the representation gap between domain speech and software.
Seven-step pruning workflow with strong/weak lists and explicit reasons, plus 4-5 case-study iteration discipline from resort to POS/ATM/library/restaurant.
Practice use-case writing, two-way diagram reading/writing, reason-tagged pruning, and 4-5 full cases within iteration scope.
Transfer of same OOA workflow across resort POS ATM library restaurant domains showing analysis choices to design domain layer.
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
Object-Oriented Analysis as Decomposition of the Problem Domain
Must-know: OOA decomposes the domain into objects after SIS/use cases; same vocabulary carries analysis→design→code.
Common pitfall: Listing nouns without purpose test; renaming between phases
Quick check: What two artifacts seed object discovery after requirements?
Connections: 8.2, 8.3
The Domain Model and the Conceptual Class Diagram
Must-know: Domain model shows conceptual classes + attributes + associations, no methods, as inspiration for design.
Common pitfall: Adding methods/visibility/navigation now; confusing with ER model
Quick check: How does conceptual class diagram differ from design class diagram?
Connections: 8.3, 8.7
What Counts as an Object and How to Test It
Must-know: Purpose test: one-two sentence domain purpose; abstraction means suppressing implementation detail.
Common pitfall: Mistaking any noun for a class; treating night as class
Quick check: Apply purpose test to Student vs night.
Connections: 8.4, 8.5
Finding Objects — Noun-Phrase Analysis, CRC Cards and Collaborative Thinking
Must-know: Noun-phrase analysis harvests candidates; CRC cards assign high-level responsibilities and collaborators via use-case walk-throughs.
Common pitfall: Turning verbs into methods now; equating responsibility with method
Quick check: What do CRC letters stand for and what is not written on a card?
Connections: 8.5, 8.6, 8.8
Intension, Extension, Classification and Abstraction
Must-know: Intension=definition, extension=instance set, representation=symbol; broad extension + crisp intension → class.
Common pitfall: Confusing extension with data flow; treating every role as class
Quick check: Classify Student vs night using intension/extension.
Connections: 8.3, 8.6
Class Versus Attribute and the Common Category Catalog
Must-know: If not a number/text in real world → class; unsure → keep as class; category list and ECB complete discovery.
Common pitfall: Modeling association as attribute (Cashier.currentRegister); letting Control become god object
Quick check: Decide city vs Store - class or attribute?
Connections: 8.7, 8.8
Associations, Glossary and Reducing the Representation Gap
Must-know: Associations are plain real-world need-to-remember lines; glossary holds preferred term and definition.
Common pitfall: Naming associations Has/Uses; adding navigability/aggregation now
Quick check: Why is glossary needed alongside domain model?
Connections: 8.2, 8.8
From Candidate List to Refined Model — Pruning, Iterations and Case Studies
Must-know: Prune only with strong reason; keep two lists; iterate within current-iteration scope; idealized behavior.
Common pitfall: Selective early filtering; expanding scope prematurely
Quick check: Name three pruning reasons and when to keep two lists.
Connections: 8.4, 8.6
Exam Guidance Summary
Must-know: Be ready to read diagram→five sentences and build diagram from text; justify every keep/drop.
Common pitfall: Memorizing lists without hands-on cases
Quick check: What is the five-sentence domain-model exercise?
Connections: 8.2, 8.8
Key Industry Applications
Must-know: Same steps transfer retail hospitality banking catalog service domains.
Common pitfall: Assuming technique is domain-specific
Quick check: Name three practice domains for end-to-end OOA.
Connections: 8.1, 8.4, 8.8
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.