Identifying Objects in Problem Statements
Nouns as Potential Objects
Read aloud is unavailable in this browser.
The Noun Extraction Technique
If there's one technique that every object-oriented designer learns early, it's this: nouns in a problem statement are candidate objects. This simple heuristic has guided countless developers from requirements to code, providing a systematic starting point for design.
But like many simple rules, its effective application requires nuance. Not every noun becomes a class. Some nouns represent attributes, others describe roles or states, and some are simply noise. The real skill lies in separating the meaningful from the meaningless—transforming a raw list of nouns into a refined set of domain objects.
This page teaches you that skill.
You will learn how to systematically extract nouns from problem statements, categorize them into objects, attributes, and noise, apply filtering criteria to identify genuine classes, and handle the edge cases that trip up most developers.
Why Nouns?
The noun-to-object mapping isn't arbitrary—it reflects a deep connection between language and software design.
In natural language, nouns represent things—concrete entities like 'customer,' 'invoice,' and 'product,' or abstract concepts like 'payment,' 'reservation,' and 'permission.' These are the subjects and objects of sentences, the entities around which actions revolve.
In object-oriented programming, classes represent things—entities that have identity, state, and behavior. They are the nouns of our code, the building blocks around which we organize logic.
This parallel isn't coincidental. Object-oriented programming was designed to model real-world (and conceptual) domains. The vocabulary of the domain—its nouns—naturally maps to the classes in an OO design.
Object-oriented design mirrors natural language: nouns become classes, verbs become methods, adjectives become attributes, and prepositions suggest relationships. This linguistic alignment is why well-designed OO code reads almost like prose.
Historical context:
The noun-extraction technique dates back to the 1980s, popularized by Rebecca Wirfs-Brock in her work on responsibility-driven design and later formalized in methodologies like the Booch Method and UML. It has stood the test of time because it works—not perfectly, but as a reliable starting point.
The technique works because:
- It's grounded in domain language — The nouns you extract come from how stakeholders describe their business
- It provides structure — Instead of staring at a blank page, you have concrete candidates to evaluate
- It's teachable and repeatable — Unlike pure intuition, it can be learned and applied consistently
- It scales — The same technique works for small features and large systems
The Extraction Process
Let's formalize the process of extracting nouns from requirements. While it seems straightforward, doing it rigorously ensures you don't miss important candidates.
Step 1: Identify All Nouns
Go through your requirements and mark every noun and noun phrase. Be inclusive at this stage—you'll filter later. Include:
- Common nouns: customer, product, order, payment
- Proper nouns: when they represent types (e.g., 'VIP Member,' 'Priority Shipping')
- Noun phrases: 'shopping cart,' 'delivery address,' 'payment method'
- Gerunds used as things: 'booking' (when it means 'a reservation'), 'shipping' (when it means 'a shipment')
- Abstract nouns: permission, status, category, type
Let's practice with this requirement:
"An online bookstore allows customers to browse books by category, add them to a shopping cart, and checkout using credit cards or gift cards. The store offers discounts for bulk purchases and loyalty points for repeat customers. Customers can track their orders and write reviews for purchased books."
1234567891011121314151617181920
Extracted Nouns and Noun Phrases:──────────────────────────────────────── 1. online bookstore2. customers3. books4. category5. shopping cart6. credit cards7. gift cards8. store9. discounts10. bulk purchases11. loyalty points12. repeat customers13. orders14. reviews15. purchased books Total: 15 noun candidatesStep 2: Create a Candidate List
Organize your extracted nouns into a table for systematic analysis. For each noun, you'll eventually determine:
- Is it a class, an attribute, or neither?
- If a class, what are its key responsibilities?
- If an attribute, which class does it belong to?
| Noun | Initial Impression | Notes/Questions |
|---|---|---|
| online bookstore | System/Context | The system itself, likely becomes the application boundary |
| customers | Strong candidate | Users who buy—clear entity with identity |
| books | Strong candidate | Core domain object |
| category | Candidate | Books belong to categories—classification entity |
| shopping cart | Strong candidate | Holds items before checkout |
| credit cards | Candidate | Payment method—could be class or enum |
| gift cards | Candidate | Payment method variant |
| store | Duplicate? | Same as 'online bookstore'? |
| discounts | Candidate | Has rules and amounts—likely a class |
| bulk purchases | Unclear | Is this a type of order or a discount trigger? |
| loyalty points | Candidate | Accumulated over time—needs tracking |
| repeat customers | Role, not class | A Customer with purchase history |
| orders | Strong candidate | Core transactional entity |
| reviews | Candidate | User-generated content with text, rating |
| purchased books | Relationship | OrderItem or Order-Book association |
At this stage, include more rather than less. It's easier to eliminate a noun later than to realize you missed an important one. The filtering process in the next section will separate the wheat from the chaff.
Categories of Nouns
Not all nouns are equal. As you analyze your candidates, you'll find they fall into distinct categories. Understanding these categories helps you make the right design decisions.
| Category | Description | Example | Design Outcome |
|---|---|---|---|
| Concrete Entity | A tangible thing with clear identity | Customer, Book, Order | Becomes a class |
| Abstract Concept | An intangible but important domain concept | Discount, Permission, Rule | Usually becomes a class |
| Role | A temporary capacity or status of another entity | Admin, VIP, Repeat Customer | Attribute, enum, or role class |
| Attribute | A simple property of another entity | Name, Price, ISBN | Becomes a field in a class |
| System Context | The system being built or its boundary | Online Store, Application | Rarely a class—it's the whole system |
| External Actor | Something outside the system that interacts with it | PaymentGateway, EmailService | Interface or adapter (integration point) |
| Event/Action Noun | A noun form of an action that happens | Purchase, Payment, Shipment | Often becomes a class (reified event) |
| Synonym/Duplicate | Same concept with different name | Store/Bookstore, User/Customer | Merge into single concept |
| Implementation Detail | Technical rather than domain concept | Database, Cache, Queue | Not a domain class—infrastructure |
The most valuable categories for OO design are:
-
Concrete Entities — These almost always become classes. They have identity (two Customers are different even if they have the same name), state (attributes change over time), and behavior (they do things).
-
Abstract Concepts — These often become classes, especially if they have their own rules and complexity. A Discount isn't just a number—it has conditions, expiration dates, and application logic.
-
Event/Action Nouns — Words like 'payment,' 'reservation,' 'shipment' represent things that happened. In well-designed systems, these are often modeled as classes so they can be tracked, audited, and reasoned about.
Reification means 'making something a thing.' When an action becomes important enough to track, store, or reason about independently, you reify it into a class. 'Customer places order' → Order class. 'User logs in' → LoginSession class. 'Package ships' → Shipment class.
Filtering Criteria: From Nouns to Classes
Now comes the crucial step: filtering your noun candidates to identify genuine classes. Apply these criteria to each candidate:
- •Has intrinsic identity — Two instances can be distinguished even if all attributes match. Is 'Customer A' different from 'Customer B' even with identical names?
- •Has attributes — The entity has properties that need to be stored or accessed. A Book has title, author, price, ISBN.
- •Has behavior — The entity does things or has things done to it. An Order can be placed, modified, cancelled, shipped.
- •Appears in multiple contexts — The same entity is referenced from different parts of the system. Customer appears in registration, ordering, and support.
- •Has lifecycle — The entity has states it moves through over time. An Order goes from 'pending' to 'paid' to 'shipped' to 'delivered.'
- •Is a thing, not a process — Processes become methods; things become classes. 'Checkout' is a process; 'Order' is a thing.
- •It's a simple value — Name, price, date, count are just data types or primitives, not entities.
- •It's redundant — Already captured by another class. 'Repeat customer' is just a Customer with purchase history.
- •It refers to the system itself — 'The online store' or 'the application' is your whole system, not a class within it.
- •It's an implementation detail — Database, cache, server, API are technical infrastructure, not domain concepts.
- •It's outside system scope — External entities you don't control (PayPal, USPS) are integration points, not domain classes.
- •It can't have multiple instances — If there's only ever one of it, it might be a singleton or module, not a class.
Applying these criteria to our bookstore example:
| Noun | Decision | Rationale |
|---|---|---|
| online bookstore | ❌ Reject | This is the system being built, not a class within it |
| customers | ✅ Class | Has identity, attributes (name, email), behaviors (browse, buy), lifecycle (registration to inactive) |
| books | ✅ Class | Core entity with title, author, ISBN; has lifecycle (in stock, out of print) |
| category | ✅ Class | Has identity (unique name), attributes (description), books belong to categories |
| shopping cart | ✅ Class | Has state (items), behaviors (add, remove, checkout), lifecycle (active to abandoned/converted) |
| credit cards | ⚠️ Maybe | Could be PaymentMethod class with subclasses, or just a string type on Order |
| gift cards | ⚠️ Maybe | Similar to credit cards—depends on whether gift cards have balance tracking |
| store | ❌ Reject | Duplicate of 'online bookstore' |
| discounts | ✅ Class | Has rules, percentage/amount, expiration, conditions—too complex for just an attribute |
| bulk purchases | ❌ Reject | This is a condition for discount, not a separate entity |
| loyalty points | ⚠️ Maybe | Could be attribute of Customer or separate LoyaltyAccount class |
| repeat customers | ❌ Reject | Role of Customer—captured by purchase history |
| orders | ✅ Class | Core transactional entity with items, totals, status, shipping info |
| reviews | ✅ Class | Has author, text, rating, date, book reference—full entity |
| purchased books | ❌ Reject | Relationship between Order and Book—becomes OrderItem or OrderLine |
Some nouns genuinely sit on the border. Whether 'loyalty points' becomes a separate class or an attribute depends on complexity. If points have complex earning rules, expiration, tiers, and redemption logic, they deserve a class. If they're just a number, they're an attribute. Context matters.
The Attribute vs Class Decision
One of the most common decisions during noun analysis is whether something should be a class in its own right or an attribute of another class. This decision has significant design implications.
Consider 'Address' in a customer management system:
- As an attribute: Customer has streetAddress, city, state, zipCode fields
- As a class: Customer has an Address object (or List<Address>)
When should Address be a class?
- •Customer can have multiple addresses (billing, shipping, work)
- •Address needs validation logic (well-formed zip codes, valid states)
- •Address is used by multiple entities (Customer, Warehouse, Supplier)
- •Address has complex formatting rules (international variants)
- •Address is compared for equality (detect duplicate addresses)
- •Each customer has exactly one simple address
- •No validation or formatting needed beyond basic strings
- •Address is never compared or manipulated as a unit
- •No other entity needs an address
- •Simplicity is valued over extensibility
The golden rule: If it has behavior, make it a class.
An Address that can format itself for display, validate itself, calculate shipping zones, or compare itself to other addresses has behavior—and thus belongs in a class.
A 'price' is usually an attribute (a simple decimal). But if price has complex behaviors—discount calculations, currency conversion, tax inclusion rules—it might become a Money or Price class.
More examples of the attribute-vs-class decision:
| Noun | Simple Case (Attribute) | Complex Case (Class) |
|---|---|---|
| Single contact email string | Multiple emails, verification status, preferences → EmailAddress class | |
| Status | Simple enum field | Complex state machine with allowed transitions → OrderStatus class |
| Date Range | startDate and endDate fields | Overlapping checks, contains logic → DateRange class |
| Money | Decimal amount field | Currency, rounding, arithmetic → Money class |
| Phone | String phoneNumber | Multiple phones, type (home/work/mobile), formatting → PhoneNumber class |
| Rating | Integer 1-5 | Weighted ratings, aggregations, trending → Rating/RatingSystem class |
When uncertain, start with the simpler choice (attribute). If you later discover complexity, refactoring an attribute into a class is straightforward. Over-engineering upfront creates unnecessary complexity. The key is recognizing when to promote.
Handling Synonyms and Duplicates
Real requirements documents are written by humans, often multiple stakeholders. This means the same concept may appear under different names, and different concepts may accidentally share a name.
Synonyms: Different Words, Same Concept
Consider these appearing in the same requirements:
- customer, buyer, user, client, patron
These might all refer to the same entity—the person who purchases from your system. Recognizing synonyms prevents you from creating redundant classes and aligns your design with a single, consistent vocabulary.
How to Handle Synonyms
- •Create a glossary — Maintain a living document mapping terms to their canonical names
- •Choose the domain-preferred term — Use what stakeholders call it most consistently
- •Standardize in code — Use one name in code, document the aliases
- •Document the decision — Note that 'client' and 'customer' refer to the same Customer class
Homonyms: Same Word, Different Concepts
The opposite problem: one word used to mean different things.
Consider 'account':
- Financial account — Where money is tracked (balance, transactions)
- User account — Login credentials and profile (username, password)
These are fundamentally different entities that happen to share a name. In code, you might have:
UserAccountorLoginAccount— Authentication and identityFinancialAccountorBillingAccount— Money management
When the same word appears to mean different things, check the context. If different stakeholders (IT vs Finance, for example) use the same term differently, each context may need its own class. This is a pattern from Domain-Driven Design called Bounded Contexts.
Detection techniques:
-
Group by responsibility — Sort your nouns by what they're responsible for. Synonyms cluster together; homonyms spread across multiple groups.
-
Ask stakeholders — When you encounter 'order' in different contexts, confirm: Is the 'order' from the warehouse and the 'order' from customer service the same thing?
-
Look at attributes — If two nouns have completely different attributes, they're probably different concepts, even if named similarly.
-
Consider lifecycle — Do the entities go through the same states? A sales order and a work order have different lifecycles—they're different classes.
Implicit and Derived Nouns
Some of the most important classes in your design don't appear explicitly in the requirements. They're implied by relationships, actions, or constraints that the requirements describe.
Implicit nouns from verbs:
When you see actions like 'customer places order,' there's an implicit noun: the placement itself. Is there value in capturing when, how, and in what context the order was placed? If yes, you've discovered an implicit class.
| Verb Phrase | Implicit Noun | When It's Needed |
|---|---|---|
| Customer pays order | Payment | Track payment status, method, history |
| Driver delivers package | Delivery | Track delivery attempts, proof, timing |
| User logs in | Session | Track active sessions, locations, devices |
| Admin approves request | Approval | Audit trail, approval chain, comments |
Implicit nouns from relationships:
When two entities are related with additional information about that relationship, there's often an implicit join entity.
"Students can enroll in courses. The system tracks their grade and enrollment date."
- Explicit nouns: Student, Course
- Implicit noun: Enrollment (the relationship carrying grade and date)
Without Enrollment as a class, you'd struggle to capture per-course grades for each student.
123456789101112131415161718
// Wrong: Where does grade go?class Student { name: string; courses: Course[]; // No place for grades!} // Right: Enrollment captures the relationship dataclass Enrollment { student: Student; course: Course; enrollmentDate: Date; grade: Grade;} class Student { name: string; enrollments: Enrollment[]; // Access courses through enrollments}Implicit nouns from collections:
When requirements describe a collection that needs its own behavior, there's often an implicit collection class.
"The shopping cart should show total price, allow removing items, and suggest related products."
The Cart isn't just a list of items—it has its own behaviors (calculate total, suggest products). It deserves to be a class, not just a List<Product> on Customer.
Ask these questions: 'What stores this information?' 'What tracks this activity?' 'What enforces this constraint?' 'What represents this relationship?' The answers often reveal implicit classes that requirements never named.
KEEP LEARNING
There’s more to understand.
You’re reading the introduction. Create a free account to read the complete lesson, save notes and keep track of your progress.