Table of Contents
Early in our development process, we won't want to be slowed down by the need to construct detailed documentation that looks "pretty" enough to show people outside our team (management or domain experts).
CRC cards are a popular way of capturing early classification steps.
CRC (Class, Responsibility, & Collaborators) cards are a useful tool during early analysis, especially during team discussions.
They are not exactly a high-tech tool:
4x6 index cards
used to take notes during analysis,
as a concrete symbol for object during discussion
cards can be stacked, moved, etc. to illustrate proposed relationships
The point of CRC cards is to capture info about an analysis discussion without slowing down that discussion so someone can take nicely formatted notes.
They aren't pretty.
They aren't something you ever want to show your customers or even your own upper-management.
If you come out of a group meeting and your CRC cards aren't smudged, dog-eared, with lots of scratched-out bits, you probably weren't really trying.
labeled with class name
divided into two columns
responsibilities
a high-level description of a purpose of the class
attributes
behaviors
collaborators
other classes to which this class must work with (send messages to) to fulfill this class's responsibilities
ClassName | |
---|---|
responsibility 1 |
|
Example:
Librarian | |
---|---|
Handles checkout and checkin of publications |
Patrons |
The responsibilities will eventually evolve into messages that can be sent to this class and then into member functions of an ADT.
That can be a good indicator of which class should receive a particular responsibility.
For example, if I were told "a library patron will give a librarian a book to be checked out", I would model this as
Librarian | |
---|---|
Handles checkout of books for patrons |
Patrons |
but not as
Patron | |
---|---|
Asks librarian to check out a book |
Librarian |
A useful rule of thumb is that if "A does B to C", then
"doing B" is a responsibility.
Usually a responsibility of C, not A
C is then a collaborator of A
Statements like "A does B to C" often occur in context like this
void A::fulfillSomeOtherResponsibilityOfA(C c1) { ⋮ c1.B(); ⋮ }
A variation on this rule of thumb occurs when managing collections.
If I told you that "the librarian adds the book's metadata to the catalog", I would expect you to model that as
Catalog | |
---|---|
Permits addition of metadata |
|
and not as
Metadata | |
---|---|
Can be added to a catalog |
|
Again, by analogy with programming, we understand that if you had something like
vector<int> v; set<int> myList; ⋮ v.push_back(23); myList.insert (23);
the operations to add new elements are operations of the container, not the element.
You would never say:
23.insertInto (myList);
A common variation is to use the backs of the cards to list attributes.
We won't do that. We'll list known attributes among the responsibilities,
By convention, "Has" introduces an attribute or list of attributes.
Librarian | |
---|---|
Handles checkout and checkin of publications |
Patrons |
Singular and plurals are used in noun phrases to distinguish between single occurrences ("name") and collections ("publications").
Avoid suggestions of specific data structures (e.g., "list of publications")
It's OK for one or the other column to wind up being empty.
An empty list of responsibilities is often associated with classes that are actors - they send messages to other classes but nothing in this world sends messages to them.
These often correspond to external systems or people who are acting spontaneously to initiate some action.
An empty list of collaborators can indicate that a class is a server - it accepts messages but sends out none. This is most likely in a "lower-level" class that is little more than a collection of attributes. Most systems have many such classes.
If both columns remain empty, however, that's a good sign that the class may not be needed in your model.
Premature design: You aren't doing code, selecting data structures, etc., yet. If you were doing those, you shouldn't be using CRC cards.
Overly specific collaborators: There is no significance between the vertical match up of the responsibilities and the collaborators, There's no implication that a particular collaborator goes with a responsibility "on the same line".
Consequently, there's no reason to list a collaborator twice.
Mis-assigned responsibilities: already discussed
Inconsistent collaboration: If you place a class B in the collaborator list of card A, then there needs to be some responsibility of B that it actually makes sense for A to call upon or make use of.
In particular, if class B has an empty responsibilities column, it really can't appear as a collaborator of anything at all!
Discuss This Page: