How to Write a Good Responsibility

Estimated reading: 7 minutes 7 views

Writing a good responsibility on a CRC card isn’t about finding the perfect verb—it’s about capturing what a class must do, without ambiguity or overlap. It’s the difference between a model that evolves with clarity and one that becomes tangled and hard to maintain.

Many beginners struggle with this because they default to vague verbs like “handle,” “manage,” or “process.” These don’t tell you what the class actually does. Instead, a well-written responsibility describes a specific, actionable duty—something the class can own and be accountable for.

Over the past two decades, I’ve seen teams fail not from poor code, but from poorly defined responsibilities. The problem isn’t the tools—they’re simple—but the mindset behind them. This chapter helps you shift that mindset.

You’ll learn how to write responsibilities that are precise, testable, and aligned with object design principles. You’ll see real examples, common mistakes, and practical refactoring strategies to keep your models clean and maintainable.

Why Responsibility Quality Matters in Object Design

Every responsibility shapes how a class behaves and how it interacts with others. A poorly worded one leads to confusion, duplication, or overloading.

Good CRC responsibilities are the foundation of responsibility-driven design. They tell you what a class is responsible for—no more, no less.

Consider this: if a class says “manage user data,” what does that mean? Is it storing it? Validating it? Encrypting it? The ambiguity leaks into implementation and collaboration. A strong responsibility eliminates guesswork.

Here’s what a good responsibility should do:

  • Be action-oriented and state what the class does directly.
  • Focus on a single duty—not a collection of tasks.
  • Be testable—you should be able to verify it through code or logic.
  • Be independent of implementation—it shouldn’t depend on how the work is done.

These aren’t abstract ideals. They’re practical guidelines that prevent design drift.

How to Write a Good Responsibility: A Step-by-Step Guide

Step 1: Start with a Clear Verb

Begin with a strong, concrete verb. Avoid weak or vague ones like “handle,” “process,” or “work with.” Instead, use verbs like “validate,” “calculate,” “persist,” “notify,” or “retrieve.”

For example:

  • Bad: “Handles payment processing.”
  • Good: “Calculates total cost with tax.”

One verb, one action. No ambiguity.

Step 2: Name the Specific Action, Not the Outcome

Focus on the action, not the result. Avoid responsibilities like “Ensures data is correct.” That’s a goal, not a responsibility.

Instead, ask: What specific step does this class take?

Examples:

  • Bad: “Ensures all user data is valid.”
  • Good: “Verifies email format using regex.”

Now you can test it. You can even write a unit test for it.

Step 3: Avoid Responsibility Overlap

One of the most common issues in CRC modeling is overlapping responsibilities. When two classes claim to “manage” the same data or logic, confusion arises.

Ask: Is this responsibility unique to this class? If not, it should be reassigned.

For example, if both User and AuthenticationService claim to “check login credentials,” one is likely doing too much.

Refactor: Let AuthenticationService own the check. Let User store the result.

Step 4: Keep It Concise and Direct

A good CRC responsibility fits on a line. It’s a simple phrase, not a sentence. Use the format: [Action] + [Object/Task].

Examples of good responsibility phrasing:

  • “Sends confirmation email.”
  • “Updates order status to shipped.”
  • “Fetches customer from database by ID.”
  • “Validates credit card number using Luhn algorithm.”

These are clear, testable, and reflect a single operational duty.

Examples of Good CRC Responsibilities in Practice

Let’s walk through a simple example: a BankAccount class.

Bad Responsibility Good Responsibility Why It’s Better
“Manages balance.” “Updates balance after deposit.” Specific action, testable, no ambiguity.
“Processes transactions.” “Records transaction in ledger.” Clear object and action; avoids vague verbs.
“Handles user info.” “Stores user name and account number.” Concrete, focused on ownership.

Notice how the good versions eliminate abstraction. They’re about what happens, not what “should” happen.

Another example: a NotificationService.

  • Bad: “Manages notifications.”
  • Good: “Sends email notification to user.”

Now it’s clear: the class’s job is sending emails, not managing the concept of notifications.

Refactoring Responsibilities: When to Split and When to Merge

Some responsibilities grow too large. If a class has five responsibilities that all relate to the same domain, it’s a red flag.

Use this decision tree:

  1. Does the responsibility involve multiple domains? (e.g., “calculates tax and sends email”) → Split.
  2. Does it describe a sequence of steps? (e.g., “handles login: checks password, creates session, logs in”) → Break into steps.
  3. Does it involve multiple objects or systems? (e.g., “updates database and notifies external service”) → Separate responsibilities.
  4. Do multiple classes claim the same duty? → Reassign to the most appropriate one.
  5. Splitting doesn’t mean creating more classes. It means reassigning ownership to improve clarity and cohesion.

    I once worked with a team who had a class called DataProcessor with 12 responsibilities. After a 15-minute CRC session, they split it into four focused classes: DataValidator, DataEncrypter, DataImporter, and DataExporter. The code became simpler, more testable, and easier to extend.

    Common Pitfalls to Avoid

    Here are the most frequent mistakes I see when teaching good CRC responsibilities:

    • Using passive voice: “Data is validated.” → Instead, “Validates user input.”
    • Using vague verbs: “Handles error.” → Instead, “Logs error to file.”
    • Describing the goal, not the action: “Ensures no duplicate accounts.” → Instead, “Checks account number against existing list.”
    • Combining multiple actions: “Fetches data and displays it.” → Split: “Retrieves data from database.” and “Displays data on screen.”

    These aren’t just stylistic choices. They reflect deeper design flaws.

    Remember: a class should do one thing, and do it well. Its responsibility should be about how it contributes to the system, not what it thinks it’s doing.

    Key Takeaways

    Writing good CRC responsibilities is not about perfection—it’s about clarity and consistency. You don’t need to get every one right on the first try. But you should aim for precision.

    Use strong verbs. Focus on actions, not goals. Avoid overlap. Keep responsibilities short and testable.

    By focusing on these principles, you build models that are not only easier to understand but also easier to extend, test, and refactor.

    These habits are the foundation of responsibility-driven examples—the kind that stand the test of time.

    Keep refining. Keep questioning. And above all, keep writing responsibilities that say exactly what the class does.

    Frequently Asked Questions

    What’s the best way to phrase a responsibility on a CRC card?

    Start with a strong verb—like “validate,” “calculate,” or “send”—followed by a specific task. Keep it concise: “Validates email format.” Avoid vague terms like “handle” or “manage.”

    How do I know if a responsibility is too broad?

    If a responsibility involves multiple steps, domains, or objects, it’s likely too broad. Split it into smaller, focused duties. Ask: “Can this be tested independently?” If not, break it up.

    Can two classes have the same responsibility?

    No. A responsibility should belong to a single class. If two classes claim the same duty, it indicates a design issue—usually poor ownership. Reassign it to the most appropriate class.

    Is it okay to use “manages” or “handles” in a responsibility?

    Not really. These verbs are too vague. They don’t clarify what the class actually does. Instead, use precise verbs like “stores,” “calculates,” or “notifies.”

    Why should I avoid passive voice in CRC responsibilities?

    Passive voice hides the actor. “Data is processed” doesn’t tell you who does it. Use active voice: “Processes customer order.” This makes ownership clear and modeling more meaningful.

    How do good CRC responsibilities improve code quality?

    They directly translate into clear method names, well-defined responsibilities, and easier unit testing. When you write good CRC responsibilities, your classes are easier to understand, maintain, and refactor—leading to cleaner, more reliable code.

Share this Doc

How to Write a Good Responsibility

Or copy link

CONTENTS
Scroll to Top