Hands-On Exercise: Modeling a Simple Banking System

Estimated reading: 7 minutes 6 views

When you’re learning object-oriented design, abstract diagrams can feel disconnected from real development. But there’s a way to ground your thinking: by building models that mirror how people actually think about systems. That’s where CRC modeling comes in. This hands-on exercise walks you through creating a simple banking system using CRC cards—providing a clear, tactile way to explore how classes, responsibilities, and collaborations interact.

I’ve guided hundreds of developers through this exact exercise. What I’ve learned is this: the real value isn’t in the final model—it’s in the dialogue. When you write responsibilities on cards and discuss how classes work together, you’re not just designing software—you’re aligning teams around shared understanding.

This CRC sample project is designed to be simple, yet rich in insight. You’ll identify core classes like Account and Transaction, assign clear responsibilities, and define how they collaborate. By the end, you’ll have a working blueprint that you can expand into a real application or translate into a UML class diagram.

Whether you’re working solo or leading a team, this CRC banking example is a proven way to practice object modeling practice with confidence.

Step 1: Identify the Core Classes

Start by asking: What are the main entities in a banking system?

Think about how a customer would describe their experience. They’d talk about accounts, transactions, balances, and maybe even branches.

Based on this, the most natural candidates are:

  • Account – Holds balance, supports deposits and withdrawals.
  • Customer – Owns one or more accounts.
  • Transaction – Records a movement of money.
  • Bank – Manages multiple accounts and handles operations.

These are your starting points. Don’t overthink the list—focus on what’s essential for this model.

Now, grab a few index cards (or use digital tools). Write each class name at the top of a card. This is where the real thinking begins.

Tip: Avoid Over-Engineering

When you first model, resist the urge to add every feature you can imagine. Start small. A simple Account class with a balance and a few actions is enough to begin.

Remember: Good modeling isn’t about completeness. It’s about clarity.

Step 2: Assign Responsibilities to Each Class

Now that you’ve defined the classes, ask: What should each one be responsible for?

Use active verbs. Be specific. Avoid vague terms like “handle” or “manage.” Instead, say “calculate interest” or “record transaction.”

Here’s how I suggest assigning responsibilities for each class:

Account

  • Store current balance
  • Accept a deposit
  • Process a withdrawal
  • Check if sufficient funds are available
  • Apply monthly interest

Notice how each responsibility is a clear, single action. This makes the class cohesive and easier to test.

Customer

  • Hold personal information (name, ID)
  • Own one or more accounts
  • Request a new account

Keep it focused. In a real system, you might add a credit check, but for now, focus on ownership and identity.

Transaction

  • Record the amount and type (deposit/withdrawal)
  • Store the timestamp
  • Link to the account involved

Transactions are passive—they record events. They don’t decide whether a withdrawal is allowed. That’s the Account’s job.

Bank

  • Manage a list of accounts
  • Create a new account for a customer
  • Apply interest to all eligible accounts monthly

Bank acts as a central coordinator. It doesn’t perform transactions—it manages the system that does.

Step 3: Define Collaborations Between Classes

Now that you know what each class does, ask: How do they work together?

Collaborations are the “who” and “how” of interaction. Instead of writing “Account talks to Bank,” describe the actual request.

Here’s how the classes interact in this model:

  • CustomerBank: Requests a new account
  • BankAccount: Creates a new instance
  • CustomerAccount: Makes a deposit or withdrawal
  • AccountTransaction: Creates a new transaction record
  • BankAll Accounts: Applies interest at month-end

Each arrow represents a call or message. You can sketch these on the cards, or write them in a small note.

Notice that the Bank doesn’t do the actual work—its role is to coordinate. The real logic lives in Account and Transaction.

This is a key insight: Collaboration is not about action—it’s about responsibility transfer.

Common Pitfall: Over-Collaboration

It’s tempting to make every class talk to every other. But that leads to high coupling and tangled logic.

Ask: Can this responsibility be better handled by another class? For example, the Bank doesn’t need to calculate interest—it delegates that to the Account.

Good collaboration keeps responsibilities close to where the data lives.

Step 4: Refine and Validate the Model

Now, step back and review. Ask:

  • Are responsibilities clear and testable?
  • Is there any duplication of work?
  • Does each class have a single, well-defined role?
  • Are collaborations logical and minimal?

Here’s a quick checklist to help:

Check Done?
Each responsibility is a single action
No class has more than 5 responsibilities
Calls flow logically from one class to another
Each class has a clear owner of data and behavior

Use this to validate your model. If anything feels off, revisit the responsibilities or collaborations.

Remember: This isn’t about getting it perfect on the first try. It’s about building a shared mental model.

As you grow more comfortable, you’ll find yourself noticing patterns—like how interest is applied only to certain account types, or how withdrawals are blocked if insufficient funds.

From Cards to Code: Translating to a Class Diagram

Once your CRC modeling is solid, you can convert it into a UML class diagram.

Each card becomes a class. Responsibilities become methods. Collaborations become associations with roles.

For example:

class Account {
  private double balance;
  public void deposit(double amount);
  public boolean withdraw(double amount);
  public void applyInterest();
}

Now you have a foundation for coding. This is where object modeling practice pays off: your design is already testable.

Later, you can add subclasses like SavingsAccount or CheckingAccount, but start simple.

Key Takeaways

This CRC banking example demonstrates how CRC modeling turns abstract design into a tangible, team-driven process.

You’ve seen how identifying classes, writing focused responsibilities, and defining logical collaborations leads to a clean, maintainable model.

Most importantly, you’ve practiced object modeling practice in a way that builds alignment, reduces ambiguity, and supports iterative design—making it a cornerstone of sound software development.

Don’t stop here. Try expanding the model by adding features like overdraft protection, customer service, or monthly statements. Each new challenge will deepen your grasp of CRC thinking.

Frequently Asked Questions

What’s the best way to start a CRC session for a banking system?

Begin with a simple question: “What happens when a customer opens an account and deposits money?” Focus on real-world behavior. Use index cards to sketch classes and responsibilities. Let the team discuss, not debate.

Can I use this CRC sample project in a classroom setting?

Absolutely. This CRC banking example is ideal for teaching object modeling practice. It’s simple enough for beginners, yet offers room to grow. Use it in workshops to encourage collaboration and early design thinking.

How do I avoid vague responsibilities like “manage data”?

Replace it with a specific action: “Store balance,” “Record transaction,” or “Validate withdrawal amount.” Use verbs that describe a concrete behavior. If you can’t name a single action, the responsibility is likely too broad.

Should I include a “Bank Manager” class in my model?

Not initially. In this model, the Bank handles coordination without adding a new class. Adding a BankManager introduces complexity that’s unnecessary for a simple system. If you later need person-in-charge roles, you can refactor.

What if two people have different ideas about a class’s responsibilities?

That’s normal—and valuable. Discuss the difference. Ask: “Who owns the data?” “Who is responsible for the outcome?” Use the model to test both ideas. The goal is clarity, not consensus.

How does this CRC modeling example help with agile development?

It supports user stories. A story like “As a customer, I want to withdraw money” maps directly to the Account’s withdraw method. CRC modeling helps break down stories into actionable, testable components—making it a natural fit for agile teams.

Now go build your own model. The cards are in your hands—your design awaits.

Share this Doc

Hands-On Exercise: Modeling a Simple Banking System

Or copy link

CONTENTS
Scroll to Top