Modeling Collaborations as Associations and Dependencies
Most beginners start with UML diagrams as if they’re the first step in design. But that’s a misunderstanding. The real beginning lies in CRC cards—simple, collaborative, and deeply rooted in team discussion. UML is not a starting tool; it’s a documentation language. When you rush into formal notation too early, you risk losing the shared understanding CRC fosters. The moment you start drawing lines and arrows without a firm grasp of who does what, you’re modeling form, not function.
My advice? Let CRC cards lead. They’re not just sticky notes with responsibilities—they’re conversations captured in real time. Once your team has explored roles, interactions, and responsibilities, you’re ready to translate those insights into structure. This chapter guides you through the critical step: turning CRC collaborations into precise UML associations and dependencies. You’ll learn how to interpret intent, assign cardinality, and decide when a link is a dependency instead of a full association. It’s not about rules—it’s about patterns, clarity, and consistency.
From Collaboration to Connection: Understanding the Intent
Every CRC collaboration is a promise: “This class needs to work with that one.” But not all promises are equal. Some are strong, persistent relationships—like a Customer owning Orders. Others are fleeting, task-based—like a PaymentProcessor calling a BankService during checkout.
These distinctions are where your skill as a designer shines. The key is to ask: Is this relationship essential for the class’s identity? If yes, it’s likely an association. If it’s temporary or conditional, it might be a dependency.
- Ask: Does the class need to hold a reference to the other?
- Ask: Is the relationship stable across multiple operations?
- Ask: Would the class fail if the other object disappeared?
If two or more of these questions are yes, proceed to model as an association. If only one or none, consider a dependency.
Recognizing the Difference: Association vs. Dependency
Confusion often arises between these two. Let me clarify with a concrete example: in a banking system, a LoanApplication class may use a CreditScoreService to check eligibility. That’s not ownership—it’s a short-term need. This is a dependency.
But if Customer has a list of Accounts, and those accounts are part of the customer’s state, that’s a full association. The customer is responsible for the life cycle of its accounts.
Use this decision tree:
- Does the class hold a reference to the other? → Association
- Is the relationship only for a single method call? → Dependency
- Is it optional or temporary? → Dependency
- Is it part of the class’s state? → Association
When in doubt, ask: “Would this class make sense without the other?” If yes, it’s likely a dependency. If no, it’s an association.
Modeling Associations: Cardinality, Navigation, and Roles
Once you confirm an association, the next step is precision. UML isn’t just about lines—it’s about meaning. Each end of the line carries cardinality, role name, and navigation direction.
Naming roles clearly is critical. Instead of just “Customer” and “Order,” use “has” or “manages” to clarify intent. For example:
Customer— hasOrderOrder— containsLineItem
Cardinality defines how many instances can exist at each end. Here’s a quick guide to common patterns:
| Cardinality | Meaning | Example |
|---|---|---|
| 1 | Exactly one | Each Order has exactly one Customer |
| 0..1 | Zero or one | A Loan may have a Guarantor |
| 1..* | One or more | A Customer has at least one Order |
| 0..* | Zero or more | A Product can be in zero or more Orders |
Navigation direction—indicated by an arrow—tells you which class owns the reference. If Customer has a list of Orders, the arrow points from Customer to Order. If Order has a reference to Customer, the arrow goes the other way.
Always validate: Can the relationship be traversed in both directions? If not, mark it accordingly. Don’t assume bidirectional navigation unless it’s truly needed.
Modeling Dependencies: The Invisible but Essential Links
Dependencies are the “I use you” relationships. They’re not part of a class’s state but are critical for behavior. The most common forms are:
- Method parameters
- Return types
- Local variables
- Class instantiation
For example, if a ReportGenerator uses a DatabaseConnection object only within one method, that’s a dependency. It doesn’t own the connection—just uses it temporarily.
UML represents dependencies with a dashed line and an arrowhead. The arrow points from the dependent to the supplier.
ReportGenerator --> DatabaseConnection
When modeling dependencies, be concise. Don’t overuse them. If you find yourself drawing too many dashed lines, ask: “Is this really a temporary need, or am I missing a deeper association?”
Here’s a checklist for when to use a dependency:
- The relationship exists only within a single method
- The object is created on the fly
- The relationship is optional or conditional
- One class is passed in as a parameter or return value
If all apply, a dependency is correct. If not, reconsider whether an association is more appropriate.
Practical Tips: Avoiding Common Pitfalls
I’ve seen teams overuse associations—every class connected to every other. That creates a tangled web that’s impossible to maintain. The key is to ask: “Does this relationship reflect real behavior, or just convenience?”
Here are three pitfalls to avoid:
- Over-associating: Don’t model every relationship as an association. If it’s not part of the class’s state or responsibility, it’s likely a dependency.
- Ignoring navigation: Always decide direction. A
Studentenrolling in aCoursedoesn’t mean the course owns the student. Navigation affects code generation and maintenance. - Confusing dependency with inheritance: Inheritance implies “is-a,” while dependency implies “uses.” Never confuse a
Carusing aEnginewith aCarbeing anEngine.
Remember: clarity beats completeness. A clean, simple model is better than a complex one that no one can read.
From CRC to UML: A Real-World Example
Let’s say your team modeled a simple inventory system using CRC cards. One card says:
- Class:
InventoryManager - Responsibility: Update stock levels based on order
- Collaboration: Works with
OrderandProduct
Now, analyze the collaborations.
First, InventoryManager and Order: The manager updates stock after an order is placed. The manager doesn’t store orders, but it needs to access order data. This is a dependency. The manager uses the order to calculate stock changes.
Second, InventoryManager and Product: The manager modifies product stock levels. It may maintain a list of products or access them via a repository. If the manager holds or manages products, this is an association.
So the correct mapping:
InventoryManager— usesOrder→ dependencyInventoryManager— managesProduct→ association
Cardinality: InventoryManager manages 0..* Products. A Product can be managed by exactly one InventoryManager.
Now you’ve translated CRC collaboration into precise UML.
Frequently Asked Questions
What’s the best way to determine whether a CRC collaboration should be an association or dependency?
Ask: “Would this class still function without the other object?” If yes, it’s likely a dependency. If no, and it holds a reference or manages the object, it’s an association. Focus on state and ownership, not just interaction.
Can a class have both associations and dependencies with the same partner?
Yes. A class might hold a reference to another (association) but still need to call a method on it in a temporary way (dependency). For example, a CustomerService may maintain a list of Customers (association) but use a NotificationService only during a specific operation (dependency).
How do I choose the cardinality in a UML association?
Base it on real-world constraints. Ask: “How many instances can exist at each end?” Use 0..1 for optional, 1 for mandatory, and 0..* or 1..* for collections. Never guess—validate with your domain experts.
What if I’m not sure about navigation direction?
Ask: “Which class is responsible for the relationship?” The class that owns or controls the reference should be the source. If a Teacher assigns a Class, the class doesn’t own the teacher—so the arrow points from Class to Teacher.
How does CRC collaboration mapping improve team communication?
CRC cards force shared understanding through discussion. When you map collaborations to UML, you’re not just drawing diagrams—you’re validating team consensus. It reduces miscommunication and ensures that every team member sees the same structure.
Can I use CRC collaboration mapping in agile environments?
Absolutely. CRC cards are ideal for sprint planning and refinement. Use them to explore interactions before writing code. Then map to UML during design reviews. It’s a lightweight, repeatable workflow that scales well with agile teams.