Classes should reflect the domain
A class name should carry business meaning, not just technical convenience.
Domain modelling is where the vocabulary of the system starts to stabilize. Instead of talking in generic terms like 'service' or 'helper,' the team begins naming the actual concepts that matter: Order, Payment, Shipment, Reservation, Refund, Notification. CRC cards remain useful because they force a direct question: what is each concept responsible for, and with whom does it collaborate?
Without domain modelling, many Java systems end up with generic service layers wrapped around passive records. CRC-style thinking pulls responsibility back toward meaningful concepts and exposes early where a design is becoming too procedural.
Domain modelling in OOAD is less about drawing boxes and more about choosing concepts that deserve first-class representation. CRC cards help because they keep the conversation simple: class, responsibility, collaborator. That format surfaces bloated objects, missing concepts, and unclear ownership quickly.
In a Java system, this process often influences aggregates, value objects, services, and package structure later on. It is much easier to build a coherent model if those responsibilities were argued in plain language before code existed.
The most valuable outcome is not a card deck. It is a shared, testable understanding of who owns which decisions.
A class name should carry business meaning, not just technical convenience.
Before listing APIs, ask what each object should know and do within the scenario.
If one concept depends on too many others to do its job, the boundary may still be wrong.
package org.javaomnibus.ecommerce.process;
public final class Order {
private final OrderId orderId;
private final CustomerId customerId;
private PaymentStatus paymentStatus = PaymentStatus.PENDING;
public Order(OrderId orderId, CustomerId customerId) {
this.orderId = orderId;
this.customerId = customerId;
}
public void markPaymentAuthorized() {
if (paymentStatus != PaymentStatus.PENDING) {
throw new IllegalStateException("Payment is already resolved");
}
paymentStatus = PaymentStatus.AUTHORIZED;
}
}
public final class InventoryReservation {
public void reserve(Order order) {
// reserve stock for the order
}
}
public enum PaymentStatus {
PENDING, AUTHORIZED
}
CRC cards can feel informal compared to heavier modeling approaches, but that simplicity is often their advantage. Use them to clarify responsibility, not to replace deeper design work entirely.