Part 3 – Designing with Objects: An Introduction to CRC Cards

We’ve discussed the power of object-oriented thinking and its importance for software design. Now, let’s get practical. How do we start designing with objects? One excellent, low-tech way to begin is by using CRC cards. These simple tools can be incredibly effective for brainstorming and exploring the relationships between objects in your design.

What are CRC Cards?

CRC stands for Class, Responsibility, and Collaborator. These cards, traditionally 3×5 index cards, are a wonderfully tactile and collaborative approach to object-oriented design. They offer a tangible and accessible entry point, particularly useful before jumping into more complex modeling tools. As the Wikipedia page on CRC cards explains, they represent a simplified method for describing the basics of object-oriented software design. I highly recommend giving that page a quick read.

How Do CRC Cards Work?

Imagine you’re designing a system. As you discuss the design, whenever you identify a potential class (a type of object), you grab a blank CRC card. On the card, you write the name of the class at the top. Below the name, you list the responsibilities of that class – what it’s supposed to do. Finally, in the right-hand column, you note the collaborators – other classes that this class needs to interact with to fulfill its responsibilities.

Let’s illustrate with an example. Suppose we’re designing a simple online store. We might identify a class called Customer. Its responsibilities might include “Place an order,” “View order history,” and “Update profile.” To place an order, the Customer class would likely need to collaborate with an Order class and a Product class. So, we’d write Order and Product in the collaborators’ column on the Customer card.

As the design discussion progresses, you might realize you also need a ShoppingCart class. You’d grab another card and start filling it out. Perhaps ShoppingCart’s responsibilities include “Add item,” “Remove item,” and “Calculate total.” It would collaborate with the Customer (to associate the cart with a customer) and the Product (to get the price of items).

The Magic of Physical Cards

The beauty of CRC cards lies in their physicality. During a design session, you physically move the cards around on the table. You lay related cards next to each other. When you introduce a new class, you place its card near the cards it interacts with. This visual representation helps you quickly grasp the relationships between different parts of your design.

You can also use the cards to “role-play” or walk through typical usage scenarios. For instance, you might simulate a customer adding items to their shopping cart by physically moving the ShoppingCart card and discussing how it interacts with the Product cards. This process helps you uncover potential design flaws or missing responsibilities early on.

Pen and Paper vs. Digital Tools

While there are web applications and software tools for creating CRC cards, I find that pen and paper work best, especially for initial brainstorming. There’s something about the tactile nature of writing on index cards and physically manipulating them that fosters creativity and collaboration. The low-tech approach also keeps the focus on the design itself, rather than getting bogged down in software intricacies. When the design starts to solidify, then a more structured digital tool can be useful for documentation.

A Simple but Powerful Technique

CRC cards might seem almost too simple, but don’t let their simplicity fool you. They’re a powerful tool for getting started with object-oriented design. They encourage collaboration, help you identify key classes and their responsibilities, and uncover potential design flaws early in the process. They’re a great way to start “thinking in objects” and building a solid foundation for your software projects.

What have you learned?

Think about a small software project you’d like to build. Even something like a simple to-do list application. Try sketching out some CRC cards for the key classes you think you’d need. What responsibilities would they have? Who would they collaborate with? Share your initial thoughts in the comments!

What’s next?

Now that you’ve got a grasp of CRC cards and how they can help you start designing with objects, let’s explore a more formal and visual approach to software design using the Unified Modeling Language, or UML. UML offers a standardized way to diagram and document your designs. Click here to continue to the next article: Visualizing Your Designs: An Introduction to UML

Special note from Michael regarding comments on this article:

When you read the comments on this page you will find a long comment by Ashuza. It’s a good one, but before you dive too deep into his comment, skip ahead to the following comment where I put some perspective on his comment. Then, based on my comment, go ahead and read at least the first parts of Ashuza’s comment.

5 thoughts on “Part 3 – Designing with Objects: An Introduction to CRC Cards”

  1. This article provides a clear and accessible introduction to CRC cards as an object-oriented design tool. The emphasis on their simplicity and accessibility is particularly valuable, as CRC cards offer a lightweight approach that does not require specialized tools or advanced technical expertise. This makes them an excellent starting point for teams looking to structure their software design collaboratively.
    The article also highlights the collaborative and brainstorming aspects of CRC cards, which is one of their key strengths. By facilitating discussions among team members, they help identify key classes, responsibilities, and collaborations, making system structuring more intuitive. This approach is particularly beneficial for teams looking to improve communication and shared understanding in the early stages of development.
    Additionally, the article mentions that CRC cards contribute to the early detection of design flaws, which is a major advantage since fixing issues later in development can be costly. However, providing more concrete examples of how CRC cards help uncover these flaws—such as missing responsibilities, excessive dependencies, or poorly defined classes—would further reinforce this point.
    While the article effectively presents the fundamental concepts, certain aspects could be expanded for greater clarity:
    • Granularity of Responsibilities: The article does not specify whether responsibilities should be broad (e.g., “Manage Orders”) or more detailed (e.g., “Validate Shipping Address”). Clarifying this would help in properly structuring class responsibilities.
    • Handling Complex Collaborations: It would be helpful to explain how to manage situations where a class interacts with multiple others, or indirectly through intermediary classes. For example, if Class A collaborates with B, which then collaborates with C, how should this be represented using CRC cards?
    • Transitioning to Digital Tools: The article acknowledges that digital tools can complement CRC cards but does not specify when or how to transition, especially in large-scale projects. Providing practical guidance on this would be valuable.
    • Evolving CRC Cards Throughout a Project: Since software design is constantly evolving, it would be useful to understand how to keep CRC cards up to date, manage conflicts, and ensure they remain aligned with the actual code.
    • Integration with Other Object-Oriented Design Methods: CRC cards are a great initial tool, but how do they integrate with more formal methodologies such as UML? Exploring how CRC cards can serve as a foundation before transitioning to structured design models would be beneficial.
    As a back-end developer, I find CRC cards particularly useful for structuring data entities and services. An effective approach involves:
    • Identifying key entities that the back-end will manage, such as data models (e.g., Product, Order, Customer, Cart), and creating CRC cards for each.
    • Defining class responsibilities related to data manipulation (e.g., “Create a product,” “Update a product”) and modeling back-end services that orchestrate these operations.
    • Mapping interactions with databases and APIs by using CRC cards for DAOs/Repositories, defining responsibilities (e.g., “Retrieve a product by ID,” “Save an order”) and identifying collaborators (e.g., the database or an ORM).
    • Clarifying front-end expectations, using CRC cards to define API contracts and ensure necessary validations or data transformations are accounted for.
    • Designing microservices efficiently, ensuring each service has a clearly defined responsibility and minimizing dependencies.
    • Preparing the transition to UML, using CRC cards to lay the groundwork before formalizing the architecture with UML diagrams (e.g., class and sequence diagrams).
    Finally, it’s crucial to follow the Single Responsibility Principle (SRP) to improve maintainability and consider design patterns, such as the Mediator pattern, to manage complex collaborations while reducing coupling.
    In conclusion, this article effectively showcases the advantages of CRC cards as a simple, collaborative, and efficient tool for object-oriented design. However, adding practical insights on handling complex collaborations, adapting designs over time, and integrating CRC cards with other methodologies would further enhance its usefulness. For teams working on larger or more complex projects, these additional details would be essential for making the most of CRC cards in real-world applications.

    Practical Example: Using CRC Cards in a “To-Do List” Application
    To illustrate the practical application of CRC cards in a real project, let’s take the example of a “To-Do List” application mentioned in the article. Here’s how you could approach the design of this project using CRC cards, leveraging the key points from the article and your back-end development expertise:

    1. Identifying Key Classes
    As a back-end developer, you can start by identifying the main data entities and the services that will handle them. Some potential classes for a To-Do List application include:
    • Task: Represents an individual task in the list.
    • TaskList: Represents the complete list of tasks.
    • User: Represents an application user.
    • TaskService: A service responsible for managing task operations.

    2. Creating CRC Cards
    For each identified class, create a CRC card and define its responsibilities and collaborators.
    Example CRC Card: “Task”
    • Class: Task
    • Responsibilities:
    o “Set the task title”
    o “Set the task description”
    o “Mark the task as completed”
    o “Set the due date”
    • Collaborators:
    o TaskList (to add or remove the task from the list)
    o User (to associate the task with a specific user)
    Example CRC Card: “TaskList”
    • Class: TaskList
    • Responsibilities:
    o “Add a task to the list”
    o “Remove a task from the list”
    o “Retrieve all tasks”
    o “Filter tasks by status (completed/incomplete)”
    • Collaborators:
    o Task (to manage individual tasks)
    o User (to associate a list with a specific user)
    Example CRC Card: “TaskService”
    • Class: TaskService
    • Responsibilities:
    o “Create a task”
    o “Update a task”
    o “Delete a task”
    o “Retrieve a task by ID”
    • Collaborators:
    o Task
    o TaskList
    o Database (or DAO/Repository)

    3. Simulating Use Case Scenarios (“Role-Playing”)
    Use CRC cards to simulate common usage scenarios and ensure the responsibilities and collaborations are correctly defined.
    Scenario: “A User Creates a New Task”
    • The user interacts with the interface (not modeled here).
    • TaskService creates a new instance of Task.
    • TaskService adds the new Task to the user’s TaskList.
    Scenario: “A User Marks a Task as Completed”
    • The user interacts with the interface.
    • TaskService updates the Task status.
    • TaskList is updated to reflect the new status.
    4. Identifying Missing Responsibilities and Collaborations
    During role-playing, you may identify missing responsibilities or incorrect collaborations. For example:
    • You might realize that the Task class needs an additional responsibility to handle task priorities.
    5. Modeling Data Persistence
    As a back-end developer, you need to consider data persistence. You can introduce a TaskDAO (Data Access Object) or a TaskRepository with responsibilities such as:
    • “Save a task to the database”
    • “Retrieve a task by ID”
    • “Update a task’s status”
    6. Collaboration with the Front-End (If Applicable)
    If working with a front-end team, CRC cards can help define API contracts clearly. For example:
    • What data should the front-end send to create a new task?
    • What response format should the back-end return when displaying a task?
    7. Transitioning to More Formal Design Tools
    Once the design is well-structured, you can use UML diagrams for documentation. This can include:
    • Class Diagrams to represent relationships between classes.
    • Sequence Diagrams to illustrate use case workflows.
    By following this approach, we use CRC cards to collaboratively and iteratively design a To-Do List application, focusing on responsibilities and collaborations between classes. This helps build a well-structured, maintainable back-end that is easy to scale and integrate with other system components.

  2. I am going to approve a long comment by Ashuza. His comment shows a great understanding of not only CRC cards and UML diagrams and their essential role in software design (from simple to very complex). His comment clearly shows that software design is an extensive discipline that is essential even in simple projects.
    I thank him for the effort and insight he invested.

    That said, I want to make sure other readers don’t get stuck in their understanding by trying to internalize all that he said. It is certainly a worthy read for those who are curious, but it’s too much to either expect our general reader to absorb, or to revise this article. It should not be viewed as a criticism of Philemon’s article.

    The bottom line is that readers of this article need to understand the basics of CRC cards, and as the last two of Philemon’s paragraphs make clear: it is time to begin the long process of putting these tools to use. The team is likely to begin a practical project using CRC cards. Those cards will go through many iterations as they work as a team to understand the necessary design. Ultimately, the cards will be left behind and UML will take over.

  3. 1. Overview and Key Takeaways

    This section of the article provides a structured introduction to CRC (Class, Responsibility, and Collaborator) cards as a valuable tool for object-oriented design. It effectively highlights the practical benefits of using CRC cards during brainstorming and early-stage design, before transitioning to more formal modeling tools like UML.

    The article emphasizes the tactile and collaborative nature of CRC cards, which facilitate a clearer understanding of relationships between different classes in a system. However, a few areas could benefit from further explanation, particularly regarding real-world applications and transitions to coding.

    Key Takeaways:

    ✅ Simplification of Initial Design Process: CRC cards make the design process more interactive and dynamic before delving into complex modeling techniques like UML.

    ✅ Real-World Example: The online store example with Customer, Order, Product, and ShoppingCart classes helps solidify understanding of object interactions within a software system.

    ✅ Encourages Collaboration: The physical nature of CRC cards makes them particularly useful for team brainstorming sessions, allowing members to visualize relationships by moving cards around.

    ✅ Bridging to UML: While CRC cards are useful for early design, a more explicit link between CRC cards and UML diagrams would help clarify the next steps in software development.

    2. Strengths and Helpful Insights

    Concise Explanation of CRC Cards The article provides a clear definition of CRC cards, explaining how they capture three key elements:

    * Class: The blueprint of an object.

    * Responsibilities: The actions it performs.

    * Collaborators: Other classes it interacts with.

    This is particularly beneficial for beginners who may struggle with conceptualizing object-oriented principles.

    Effective Use of Examples The online store example is well-structured and includes essential class responsibilities such as:

    ShoppingCart: “Add item,” “Remove item,” “Calculate total.”

    Customer: “Place an order.”

    Order: “Process payment.”

    These examples effectively illustrate real-world object interactions. However, a more complex scenario (e.g., a library management system) could further demonstrate how CRC cards handle intricate relationships and dependencies.

    Remarkable Question: How do CRC cards scale when dealing with larger systems involving inheritance and polymorphism?

    Physical Interaction as a Strength Highlighting the tactile nature of CRC cards (moving them around, grouping them) is an insightful approach, especially for team brainstorming sessions. However, the article does not fully explain how this process helps uncover missing relationships or flaws in object design.

    Remarkable Question: How does physically moving CRC cards help reveal missing interactions or errors in the design process?

    Clarification Example:

    Suppose a Customer places an order. Moving the Customer card next to the ShoppingCart card may reveal a missing connection—should the ShoppingCart be linked to an Order before checkout?

    Physically moving the cards forces developers to think critically about object relationships, improving design decisions.

    Comparison Between Pen & Paper vs. Digital Tools The article discusses the benefits of low-tech brainstorming before transitioning to structured digital tools like UML. This is crucial, as many developers rush into coding or software modeling without first conceptualizing relationships. However, the article could briefly mention tools like Miro or Trello for teams that collaborate remotely.

    Remarkable Question: What are the best digital tools for remote CRC card collaboration?

    3. Areas for Improvement and Unclear Points

    Unclear Explanation of Role-Playing Concept The role-playing approach—where developers act as objects and simulate interactions—is mentioned but not fully explained. A detailed walkthrough (e.g., how a Customer interacts with an Order) would make this concept more practical.

    Remarkable Question: How can role-playing with CRC cards improve team understanding of object behaviors?

    More Emphasis on the Transition to UML The article briefly mentions UML but does not clearly explain how CRC cards translate into UML diagrams.

    Remarkable Question: What are the step-by-step stages from a CRC card to a UML class diagram?

    Suggested Enhancement:

    Show a before-and-after comparison of a CRC card and its equivalent UML diagram.

    Explain how responsibilities translate into methods and how collaborators become associations in UML.

    How Do CRC Cards Translate into Code? The article does not discuss how CRC cards transition from design to actual implementation in code. Including an example would clarify this gap.

    Remarkable Question: How do CRC cards influence actual class structure in coding languages?

    Example Implementation in JavaScript:

    javascript
    class Customer {
    placeOrder(cart) {
    let order = new Order(cart.items);
    order.processPayment();
    }
    }
    Here, the Order class and ShoppingCart class (collaborators) appear as dependencies in the code, demonstrating how CRC card planning directly informs real-world software development.

    4. Key Questions and Suggested Enhancements

    Handling Inheritance and Polymorphism Remarkable Question: How do CRC cards represent parent-child relationships in object-oriented programming?

    Suggested Enhancement:

    Provide an example showing how subclasses can be represented using CRC cards (e.g., a base Payment class with CreditCardPayment and PayPalPayment as subclasses).

    Iterative Nature of CRC Cards CRC cards are often refined over multiple iterations as the design evolves. However, the article does not mention how to adapt CRC cards when new insights emerge.

    Remarkable Question: How can developers iterate on CRC cards to improve design clarity over time?

    Suggested Enhancement:

    Show an example of how CRC cards evolve from an initial draft to a refined design.

    No Mention of CRC Limitations or Alternative Methods CRC cards are excellent for small-scale projects, but they may not be ideal for large-scale systems with numerous relationships. The article could briefly discuss when to switch from CRC cards to UML or database schema modeling.

    Remarkable Question: When do CRC cards become too simplistic, and what alternatives should developers consider?

    5. Conclusion and Final Thoughts

    Overall, this article effectively introduces CRC cards in a clear, simple, and engaging manner. The emphasis on hands-on interaction and real-world examples makes it accessible for beginners. However, a stronger connection to real coding, UML transitions, and iterative design would enhance understanding.

    Next Steps for Practical Application

    Since I believe in learning by doing, I plan to apply CRC cards to a to-do list application, sketching out potential classes and their responsibilities. I encourage others to try this exercise—it’s a great way to grasp the practical benefits of CRC cards before moving into digital modeling tools.

    * Experiment with CRC cards in your projects.

    * Explore how CRC cards can be adapted for remote collaboration using digital tools.

    * Practice translating CRC cards into code and UML diagrams to solidify your understanding.

    CRC cards are a powerful way to think in objects before diving into code. By using them effectively, developers can create cleaner, more maintainable architectures—which is an essential skill in modern software development.

    1. Excellent comments Efatha!
      You are asking exactly the right questions and coming up with good answers yourself. This means that Philemon did his job of explaining just the right amount.

      It’s now time for the team to get hands on the job. Bring your questions and ideas to the table and work as a team to start using the CRC cards. It’s a low tech way to get you thinking ahead.

      You asked about how CRC cards can be formalized and scaled up. The simple answer is that they don’t. They were not meant to scale or get too formalized. That is the job of UML.

      I have proposed to Philemon that the team or at least part of it try a real world example using an application that you have already had some experience with. My suggestion is the Demo application that the three of you did last year. You already had the non design experience and got it working.

      I will leave that to you all as a team to coordinate a project together. Once you come to a consensus, you can propose what you plan to do and I’ll write up an Upwork job for it.

      In doing that project you will learn starting with CRC cards and quickly move on to UML diagrams. They scale well and are more easily modified and adapted as the design progresses.

Leave a Reply

Your email address will not be published. Required fields are marked *