UML Diagrams for Program Decomposition
Introduction: From Words to Code - The Nouns and Verbs Approach
As a beginner programmer, you might think that the hardest part of programming is learning syntax and remembering method names. But experienced developers know the real challenge: identifying the key entities (things) and behaviors (actions) hidden in problem descriptions, then organizing them into working code.
UML (Unified Modeling Language) diagrams are like blueprints for software. Just as an architect draws plans before building a house, smart programmers sketch their class designs before writing code. This guide will walk you through using UML class diagrams to decompose the DiceyLab project step by step, using the powerful “nouns and verbs” technique.
Key Insight: Hand-drawn UML diagrams are thinking tools that help you discover the entities in your problem domain. Once you identify what “things” exist and what “actions” they can perform, the code structure becomes obvious.
Step 1: Entity Discovery - Finding the Nouns and Verbs
The first step in program design isn’t thinking about code—it’s thinking about the problem domain. We need to identify the key entities (nouns) and their behaviors (verbs) from the requirements.
The Nouns and Verbs Technique
When you read a problem description, mentally highlight:
- Nouns → These become your entities (classes/structures) and attributes (instance variables)
- Verbs → These become your methods (functions/behaviors)
Let’s apply this to the DiceyLab project requirements:
Analyzing the DiceyLab Problem Statement
Problem Description: “Create a dice simulation where multiple dice are thrown many times to track the distribution of results. The simulation should roll dice, count outcomes, and display statistical results.”
Nouns (Things/Entities):
- Dice - The physical objects being simulated
- Simulation - The experiment process itself
- Results - The collection of outcomes
- Distribution - The pattern of outcomes
- Outcomes/Bins - Individual result categories
Verbs (Actions/Behaviors):
- Roll/Toss - Generate random values
- Track/Count - Record what happened
- Display/Print - Show the results
- Run/Execute - Perform the experiment
Entity Emergence Process
From this analysis, three key entities emerge:
- Dice Entity - Represents the dice being rolled
- Bins Entity - Represents the result tracking system
- Simulation Entity - Represents the experiment orchestrator
Why these entities? Each represents a distinct “thing” in our problem domain with its own:
- State (what it knows/remembers)
- Behavior (what it can do)
- Responsibility (what it’s in charge of)
Example Usage Patterns
// Creating dice
dice = CREATE Dice(2) // for craps
toss = CALL dice.tossAndSum()
// Tracking results
results = CREATE Bins(2, 12) // for bins from 2..12
CALL results.incrementBin(10)
numberOfTens = CALL results.getBin(10)
// Running simulation
sim = CREATE Simulation(2, 10000)
CALL sim.runSimulation()
CALL sim.printResults()
Step 2: From Entities to UML - Mapping Nouns and Verbs
Now that we’ve identified our entities, let’s map them to UML class diagrams. In UML, each entity becomes a class with three sections:
- Top section: Entity name (the main noun)
- Middle section: Attributes (descriptive nouns - what the entity knows)
- Bottom section: Methods (verbs - what the entity can do)
Entity 1: The Dice Entity
Nouns associated with Dice:
- numberOfDice (how many dice in the set)
- sides (implied - standard 6-sided)
Verbs associated with Dice:
- roll/toss (generate random values)
- sum (add up multiple dice)
classDiagram class Dice { -int numberOfDice +Dice(int numberOfDice) +int tossAndSum() }
Entity Analysis:
- What it knows: How many dice it represents
- What it does: Generates random dice rolls and sums them
- Why it exists: Encapsulates the concept of “a set of dice”
Entity 2: The Bins Entity
Nouns associated with Bins:
- minValue, maxValue (the range of possible outcomes)
- bins/counts (the collection of result tallies)
- value (specific outcome being tracked)
Verbs associated with Bins:
- increment (add to a count)
- get (retrieve a count)
- track (overall responsibility)
classDiagram class Bins { -int minValue -int maxValue -int[] bins +Bins(int minValue, int maxValue) +void incrementBin(int value) +int getBin(int value) }
Entity Analysis:
- What it knows: The range of values and current counts
- What it does: Tracks frequency of different outcomes
- Why it exists: Encapsulates the concept of “statistical collection”
Entity 3: The Simulation Entity
Nouns associated with Simulation:
- numberOfDice, numberOfTosses (experiment parameters)
- dice (the dice being used)
- results (the bins collecting data)
Verbs associated with Simulation:
- run (execute the experiment)
- print (display results)
- orchestrate (overall coordination)
classDiagram class Simulation { -int numberOfDice -int numberOfTosses -Dice dice -Bins results +Simulation(int numberOfDice, int numberOfTosses) +void runSimulation() +void printResults() }
Entity Analysis:
- What it knows: Experiment parameters and references to other entities
- What it does: Coordinates the overall experiment
- Why it exists: Encapsulates the concept of “the experiment process”
Step 3: Entity Relationships - How Things Interact
Now let’s discover how our entities relate to each other. In object-oriented design, entities don’t exist in isolation—they collaborate to solve the problem.
Relationship Discovery Through Verbs
Look at the verbs associated with each entity:
- Simulation needs to use Dice (to get random values)
- Simulation needs to use Bins (to record results)
- Dice and Bins don’t directly interact with each other
This gives us our entity relationship diagram:
classDiagram class Dice { -int numberOfDice +Dice(int numberOfDice) +int tossAndSum() } class Bins { -int minValue -int maxValue -int[] bins +Bins(int minValue, int maxValue) +void incrementBin(int value) +int getBin(int value) } class Simulation { -int numberOfDice -int numberOfTosses -Dice dice -Bins results +Simulation(int numberOfDice, int numberOfTosses) +void runSimulation() +void printResults() } Simulation --> Dice : uses Simulation --> Bins : uses
Key Entity Relationships:
- Simulation uses Dice: The simulation entity creates and uses a Dice entity to generate random values
- Simulation uses Bins: The simulation entity uses a Bins entity to track results
- Composition pattern: Simulation “has-a” Dice and “has-a” Bins
Step 4: Refining Entities - Discovering Hidden Nouns and Verbs
As you think deeper about the implementation, you’ll discover additional nouns and verbs that weren’t obvious in the initial analysis. This is normal and shows your understanding is deepening.
Hidden Nouns (Additional Attributes)
- rollSingleDie - the action of rolling one individual die
- index - position within the bins array
- toString - string representation of results
Hidden Verbs (Additional Methods)
- calculateMinMax - determining the range of possible values
- getIndex - converting values to array positions
Refined Entity Design
classDiagram class Dice { -int numberOfDice +Dice(int numberOfDice) +int tossAndSum() -int rollSingleDie() } class Bins { -int minValue -int maxValue -int[] bins +Bins(int minValue, int maxValue) +void incrementBin(int value) +int getBin(int value) +String toString() -int getIndex(int value) } class Simulation { -int numberOfDice -int numberOfTosses -Dice dice -Bins results +Simulation(int numberOfDice, int numberOfTosses) +void runSimulation() +void printResults() -void calculateMinMax() } Simulation --> Dice : uses Simulation --> Bins : uses
Why These Additions Matter:
- Private methods represent internal verbs - actions the entity does for itself
- Helper methods break complex behaviors into simpler parts
- This refinement shows how analysis evolves as understanding deepens
Step 5: Hand-Drawn Diagrams - Thinking Tools for Entity Discovery
Why Hand-Drawing Matters for Entity Analysis
Computer-generated diagrams are nice, but hand-drawn sketches are entity discovery tools. Here’s why:
- Speed: You can sketch entities as you discover them
- Flexibility: Easy to add new nouns and verbs as you find them
- Focus: Forces you to think about essential entities, not visual perfection
- Accessibility: Works anywhere - no computer needed for entity analysis
- Collaboration: Easy to share entity insights with teammates
Hand-Drawing Tips for Entity Modeling
Basic Entity Box (Noun → Attributes → Verbs):
┌─────────────┐
│ Dice │ ← Entity name (main noun)
├─────────────┤
│-numberOfDice│ ← Attributes (descriptive nouns)
│-sides │ ← What the entity "knows"
├─────────────┤
│+tossAndSum()│ ← Methods (verbs)
│-rollSingle()│ ← What the entity "does"
└─────────────┘
Show Entity Relationships:
Simulation ───→ Dice (Simulation uses Dice)
│
└───→ Bins (Simulation uses Bins)
Annotate with Entity Questions:
┌─────────────┐
│ Simulation │ ← What entity orchestrates?
├─────────────┤
│-numberOfDice│ ← What does it need to know?
│-tosses │
│-dice │ ← What entities does it use?
│-results │
├─────────────┤
│+runSim() │ ← What verbs make sense?
│+printRes() │
└─────────────┘
The Entity Discovery Process
Step 1: Entity Identification
- Read problem statement
- Circle all nouns → potential entities/attributes
- Underline all verbs → potential methods
Step 2: Entity Grouping
- Group related nouns together
- Each group becomes a potential entity
- Ask: “Does this group represent a single concept?”
Step 3: Entity Validation
- Can you describe what the entity “is”?
- Can you list what it “knows”?
- Can you list what it “does”?
- Does it have a clear responsibility?
Step 6: From Entity Design to Implementation
Entity-Driven Implementation Order
Now that we understand our entities, we can implement them in logical order based on their dependencies:
Implementation Strategy:
- Start with entities that have no dependencies (Dice)
- Then entities that depend only on simple data (Bins)
- Finally, entities that orchestrate others (Simulation)
Implementing the Dice Entity
The Dice entity encapsulates the concept of “a set of rollable dice”:
FUNCTION create_dice(numberOfDice):
dice = new object
dice.numberOfDice = numberOfDice // Entity attribute (noun)
RETURN dice
FUNCTION toss_and_sum(dice): // Entity behavior (verb)
sum = 0
current = 1
WHILE current <= dice.numberOfDice:
roll = CALL roll_single_die() // Helper behavior (verb)
sum = sum + roll
current = current + 1
RETURN sum
FUNCTION roll_single_die(): // Private entity behavior
random_value = RANDOM_NUMBER_0_TO_1() * 6
die_value = FLOOR(random_value) + 1
RETURN die_value
Entity Analysis:
- Main noun: dice (the thing we’re modeling)
- Attributes: numberOfDice (what it knows about itself)
- Primary verb: toss_and_sum (what others ask it to do)
- Helper verb: roll_single_die (what it does internally)
Testing Entity Behavior
Before implementing the next entity, verify this entity works:
dice = CREATE Dice(2)
counter = 1
WHILE counter <= 10:
result = CALL dice.tossAndSum()
PRINT result
counter = counter + 1
This test validates the entity’s core behavior (the main verb).
Implementing the Bins Entity
The Bins entity encapsulates the concept of “statistical result collection”:
FUNCTION create_bins(minValue, maxValue):
bins = new object
bins.minValue = minValue // Entity attributes (nouns)
bins.maxValue = maxValue
bins.bins = CREATE_ARRAY(maxValue - minValue + 1)
// Initialize all bins to 0
index = 0
WHILE index < LENGTH(bins.bins):
bins.bins[index] = 0
index = index + 1
RETURN bins
FUNCTION increment_bin(bins, value): // Entity behavior (verb)
IF value >= bins.minValue AND value <= bins.maxValue:
array_index = CALL get_index(bins, value) // Helper verb
bins.bins[array_index] = bins.bins[array_index] + 1
FUNCTION get_bin(bins, value): // Entity behavior (verb)
IF value >= bins.minValue AND value <= bins.maxValue:
array_index = CALL get_index(bins, value)
RETURN bins.bins[array_index]
RETURN 0
FUNCTION get_index(bins, value): // Private entity behavior
RETURN value - bins.minValue
Entity Analysis:
- Main noun: bins (the collection of result counts)
- Attributes: minValue, maxValue, bins array (what it knows)
- Primary verbs: increment_bin, get_bin (what others ask it to do)
- Helper verb: get_index (internal calculation)
Implementing the Simulation Entity
The Simulation entity encapsulates the concept of “experiment orchestration”:
FUNCTION create_simulation(numberOfDice, numberOfTosses):
simulation = new object
simulation.numberOfDice = numberOfDice // Entity attributes
simulation.numberOfTosses = numberOfTosses
simulation.dice = CALL create_dice(numberOfDice) // Entity relationships
// Calculate min and max possible values (derived attributes)
minValue = numberOfDice * 1 // all ones
maxValue = numberOfDice * 6 // all sixes
simulation.results = CALL create_bins(minValue, maxValue)
RETURN simulation
FUNCTION run_simulation(simulation): // Primary entity behavior
toss_count = 1
WHILE toss_count <= simulation.numberOfTosses:
toss_result = CALL toss_and_sum(simulation.dice) // Uses Dice entity
CALL increment_bin(simulation.results, toss_result) // Uses Bins entity
toss_count = toss_count + 1
FUNCTION print_results(simulation): // Entity behavior (verb)
PRINT "Simulation of " + simulation.numberOfDice +
" dice tossed for " + simulation.numberOfTosses + " times."
value = simulation.numberOfDice
WHILE value <= simulation.numberOfDice * 6:
count = CALL get_bin(simulation.results, value) // Uses Bins entity
percentage = count / simulation.numberOfTosses
PRINT FORMAT_NUMBER(value, 2) + " : " +
FORMAT_NUMBER(count, 8) + ": " +
FORMAT_DECIMAL(percentage, 2)
value = value + 1
Entity Analysis:
- Main noun: simulation (the experiment process)
- Attributes: numberOfDice, numberOfTosses (experiment parameters)
- Relationships: dice, results (references to other entities)
- Primary verbs: run_simulation, print_results (orchestration behaviors)
Step 7: Entity Validation and Design Reflection
Questions Your Entity Analysis Should Answer
- What real-world concepts does each entity represent? (Main nouns)
- What information does each entity need to remember? (Attribute nouns)
- What can other entities ask this entity to do? (Public verb methods)
- What does this entity do internally? (Private verb methods)
- How do entities collaborate to solve the problem? (Relationships)
Entity Design Quality Indicators
Good Entity Design:
- Single Responsibility: Each entity models one clear concept
- Meaningful Names: Entity and method names reflect real-world nouns and verbs
- Clear Boundaries: It’s obvious what each entity is responsible for
- Natural Interactions: Entity relationships make sense in the problem domain
Poor Entity Design:
- God Entities: One entity that does everything
- Anemic Entities: Entities with only data, no behavior
- Confused Responsibilities: Can’t clearly explain what an entity represents
Common Entity Discovery Issues
Missing Entities: If you can’t implement a behavior with your current entities, you may be missing an important concept from the problem domain.
Wrong Abstraction Level: If your entities are too detailed (like “LeftDie” and “RightDie”) or too general (like “GameManager”), reconsider the natural concepts in your problem.
Circular Dependencies: If Entity A needs Entity B and Entity B needs Entity A, you may have incorrectly identified entity boundaries.
Step 8: Advanced Diagram Techniques
Adding Detail as Needed
Show Data Types:
┌─────────────────┐
│ Dice │
├─────────────────┤
│-numberOfDice:int│
├─────────────────┤
│+tossAndSum():int│
└─────────────────┘
Show Function Parameters:
┌─────────────────────┐
│ Bins │
├─────────────────────┤
│-bins: array of int │
├─────────────────────┤
│+incrementBin(val:int)│
│+getBin(val:int):int │
└─────────────────────┘
Add Notes for Tricky Parts:
┌─────────────┐ ┌──────────────────────┐
│ Simulation │────→│ Note: Calculate min/ │
└─────────────┘ │ max based on number │
│ of dice (1*n to 6*n) │
└──────────────────────┘
The Power of Sketching: Real-World Benefits
For Beginner Programmers
Entity-driven UML diagrams teach you to:
- Think in Terms of Real-World Concepts: Identify the “things” and “actions” in problem descriptions
- Break Down Problems Naturally: Use noun and verb analysis to discover entities
- See Entity Relationships: Understand how different concepts collaborate
- Catch Design Problems Early: Validate entities before implementing them
- Communicate Conceptually: Share your understanding of the problem domain
The Entity Discovery Workflow
The Noun-Verb-Entity Cycle:
- Analyze problem statement for nouns and verbs
- Group related concepts into potential entities
- Validate each entity’s purpose and responsibilities
- Design entity relationships and interactions
- Implement entities in dependency order
- Refine based on what you learn during implementation
Why Hand-Drawing Beats Digital Tools for Entity Discovery
For learning entity modeling, pencil and paper win because:
- Natural thinking flow: Match the way your brain processes concepts
- No tool constraints: Focus on concepts, not software features
- Easy concept iteration: Quick to modify as understanding evolves
- Collaborative discovery: Easy to share insights during group analysis
- Portable analysis: Work anywhere, anytime for problem analysis
Common Beginner Mistakes and How Entity Analysis Helps
Mistake 1: Starting to Code Without Understanding Entities
Without Entity Analysis: Jump into coding without understanding what you’re modeling
With Entity Analysis: Spend time identifying the key concepts before writing any code
Mistake 2: Creating God Entities
Without Entity Analysis: One entity that represents everything in the problem
With Entity Analysis: Natural entity boundaries emerge from noun groupings
Mistake 3: Missing Core Entities
Without Entity Analysis: Realize halfway through that you’re missing a key concept
With Entity Analysis: Systematic noun analysis reveals all important entities upfront
Mistake 4: Confusing Entity Relationships
Without Entity Analysis: Unclear how different parts of your system should interact
With Entity Analysis: Verb analysis reveals natural collaboration patterns
Practice Exercise: Entity Discovery for New Features
Now that you understand entity analysis for DiceyLab, try discovering entities for these extensions:
Feature 1: Different Die Types
Problem Statement: “Support various die types including 4-sided, 8-sided, and 20-sided dice in the simulation.”
Entity Discovery Questions:
- What new nouns appear? (die types, sides, shapes)
- What new verbs appear? (configure, validate die types)
- Should “die type” be an attribute or a separate entity?
- How do existing entities need to change?
Feature 2: Detailed Statistics
Problem Statement: “Track advanced statistics including average roll, standard deviation, and comparison between theoretical and actual probabilities.”
Entity Discovery Questions:
- What is the main new entity? (Statistics, Calculator, Analyzer?)
- What would this entity know? (averages, deviations, expectations)
- What would this entity do? (calculate, analyze, compare)
- How would it relate to existing entities?
Feature 3: Multiple Output Formats
Problem Statement: “Generate results in multiple formats including console display, file output, and CSV export.”
Entity Discovery Questions:
- Are “Console”, “File”, and “CSV” separate entities or one “OutputFormatter” entity?
- What verbs are associated with output? (format, write, export, display)
- How should output entities relate to the Simulation entity?
- What attributes would each output entity need?
Final Advice: Make It a Habit
Start Every Programming Assignment with Entity Discovery
Before you write any code:
- Read the requirements carefully, highlighting nouns and verbs
- Group related nouns into potential entities
- Validate each entity’s purpose and responsibilities
- Sketch entity diagrams showing attributes and methods
- Map relationships between entities
- Implement entities in dependency order
Keep Your Entity Analysis
Your entity discovery work is valuable because it:
- Shows your problem-understanding process
- Helps you remember design decisions
- Provides great reference material for similar problems
- Demonstrates systematic thinking to instructors
Remember: Perfect Entities Aren’t the Goal
The goal is clear problem understanding. A rough entity analysis that helps you understand the problem domain is infinitely more valuable than a perfect diagram that doesn’t teach you anything about the real-world concepts you’re modeling.
Think of entity analysis as a lens for understanding problems - it helps you see the natural structure hidden in problem descriptions. Eventually, you’ll automatically think in terms of entities and their relationships, but you’ll still use this analysis process for complex domains.
The best programmers aren’t those who memorize syntax - they’re those who can discover the essential entities in any problem domain and understand how those entities should collaborate. UML diagrams with the nouns-and-verbs approach are powerful tools for developing this crucial skill.