Welcome~~~


Another blog:
http://fun-st.blogspot.com/

It is easier to write an incorrect program than understand a correct one.

Sunday, February 13, 2011

CSCI 581 (Object-Oriented Design) Lecture Notes on Using CRC Cards

CSCI 581 (Object-Oriented Design) Lecture Notes on Using CRC Cards


Using CRC Cards: ATM Case Study

Sources for the Candidate Classes

Before the brainstorming session, assign each team member an investigative task [Bellin and Simone]:
  • Read all requirements documents
    • Examine the formal requirements document (if any)
    • Don't overlook the indirect sources -- memos, meeting minutes, etc.
    • Circle nouns and noun phrases -- these are potential classes
  • Look carefully at reports
    • Examine the reports generated in the system being replaced (manual or automated)
    • Examine the profiles for the reports desired in the new system
    • Again circle nouns and noun phrases -- these are potential classes
  • Conduct interviews
    • Talk to experienced users of the current system
    • Record interview or take careful, precise notes
    • Again identify nouns and noun phrases as candidate classes
  • Examine documentation and files
    • Review the documentation on the current system
    • Try to review any unofficial or personal notes users or maintainers of the system have
    • Again identify nouns and noun phrases as candidate classes
A good analyst is a good detective!

Requirements for an Automated Teller Machine (ATM)

University Bank will be opening in Oxford, Mississippi, in January, 2000. We plan to use a full service automated teller machine (ATM) system.
The ATM system will interact with the customer through a display screen, numeric and special input keys, a bankcard reader, a deposit slot, and a receipt printer.
Customers may make deposits, withdrawals, and balance inquires using the ATM machine, but the update to accounts will be handled through an interface to the Accounts system.
Customers will be assigned a Personal Identification Number (PIN) and clearance level by the Security system. The PIN can be verified prior to any transaction.
In the future, we would also like to support routine operations such as a change of address or phone number using the ATM

Candidate Classes for the ATM

By brainstorming, we might identify the following candidate classes for University Bank's ATM system [Bellin and Simone]:

ATM FinancialTransaction BankCard
BankCustomer PIN Account
SavingsAccount CheckingAccount Transfer
Withdrawal Deposit BalanceInquiry
Receipt ReceiptPrinter Keypad
Screen CashDispenser ScreenMessage
Display FundsAvailable DepositEnvelopeFailure
Balance TimeOutKey TransactionLog
Key AccountHolder Printer
ScreenSaver Prompt NumericKey


Identifying Core Classes

Moving from brainstorming to analysis, divide the candidate classes into categories in the following order:
  1. critical classes (i.e., the "winners"), for which we will definitely write CRC cards Items that directly relate to the main entities of the application
    In the ATM example: Account, Deposit, Withdrawal, BalanceInquiry
  2. irrelevant candidates (i.e., the "losers"), which we will definitely eliminate Items that are clearly outside the system scope
    In the ATM example: Printer, ScreenSave, and Prompt -- related to the user interface subsystem to be done later, but not to the core banking application
  3. undecided candidates (i.e., the "maybes"), which we will review further for categorization Items that we may not be able to categorize without first clarifying the system boundaries and definition
    In the ATM example: What is an "ATM"?

Clarifying System Scope

To continue design, we must determine what is and what is not part of the system.
What is the scope of the ATM system in the example?
Possible questions:
  • Does it handle everything--the banking application, the user interface, and the interactions between them?
  • Is the ATM responsible for updating accounting records? or just recording and mediating the transaction activity?
The system boundary should be the product of definite decision making.
It is often useful to draw a diagram to record system boundaries.
ATM example: limit its scope to the banking information capture -- leaving the user interface and actual account update to other systems

Architectural Design Issues

  • Identify hot spots. Structure classes and collaborations accordingly. A hot spot is a portion of the system that is likely to change from one system variant to another.
    Encapsulate the variable aspects within components. Design the interfaces of and the relationships among components so that change is seldom necessary.
    Enables convenient reuse of the overall system architecture and common code. Makes change easier to implement at hot spots.
    ATM example: withdrawal handling is a hot spot. Initially supports the dispensing of cash; future may require update of cash cards. The classes that touch this hot spot include Account, Withdrawal, FundsAvailable, and BankCard.

  • Use appropriate design patterns to guide structuring of the system. A design pattern is a design structure that has been successfully used in a similar context--a reusable design.
    Design patterns may be distillations of development organization experience -- or may be well-known general patterns selected from a book such as Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four (Gamma, Helm, Johnson, and Vlissides) (Addison-Wesley, 1995).
    The use of the design pattern may require the addition of new classes to the design.
    ATM example: The interactions of the ATM with outside entities might be modeled using a "system interaction pattern". This would result in a new core class AuthorizeSystemInteraction.

  • Take advantage of existing software frameworks. A framework is a collection of classes--some abstract, some concrete--that captures the architecture and basic operation of an application system. Systems are created by extending the given classes to add the specialized behaviors.
    Frameworks are "upside down libraries" -- system control resides in framework code that calls "down" to user-supplied code.
    Example: Graphical user interface toolkits like the Java AWT.
    To fit an application into a framework may require addition or modification of core classes.

Eliminate Unnecessary Core Classes

  • Remove ghost classes -- classes that, upon further examination, do not fit within the application Look for classes that are related entities but are outside the system. We may need to interface to these entities, but do not need to model them within the system.
    ATM example: BankCustomer, Printer, and Keypad are relevant but outside the application being developed. For example, the system only needs to know about BankCustomer indirectly through the BankCard information such as the PIN.

  • Combine synonyms -- use only one name for items that are essentially the same. This situation may arise when different groups within an organization use different names to refer to the same thing.
    ATM example: BankCustomer and AccountHolder are probably synonyms. Adopt one of them or create a new name.
    ATM example: Balance and FundsAvailable may be different concepts. The Balance of some Account and the FundsAvailable for withdrawal may not be the same because of a policy of disallowing withdrawals for some period after deposit of a check.
    Be careful when the same word actually refers to different things! New core classes may be needed.

  • Distinguish attributes (data elements) from classes. Some candidate classes may turn out to represent information held by other objects instead of being classes themselves.
    A candidate class may be an attribute rather than a class if:
    • it does not do anything -- it has no operations ATM example: Balance and FundsAvailable (mentioned above) have few meaningful operations and both are closely associated with Account.
    • it cannot change state ATM example: Consider a PIN. If a PIN is viewed as being immutable, not changing state, then it probably should be an attribute of Account. However, if a PIN can change state--say from among valid, invalid, and suspended--then it should be a class.

Annotated Candidate Class List for the ATM

Core Classes

FinancialTransaction
Account
BalanceInquiry
Withdrawal
Deposit
AuthorizeSystemInteraction
BankCard

Undecided Classes

BankCustomer (ghost - integrated with AuthorizeSystemInteraction)
PIN (attribute)
SavingsAccount (attribute of Account)
CheckingAccount (attribute of Account)
ATM (ghost -- system name)
FundsAvailable (attribute)
Balance (attribute)
AccountHolder (synonym)

Irrelevant Items

These are outside the scope of the system. Many are candidates for classes in the user interface system.
Transfer (not handled in first version)
Receipt
ReceiptPrinter
Keypad
Screen
CashDispenser
ScreenMessage
Display
DepositEnvelopeFailure
TimeOutKey
TransactionLog
Printer
ScreenSaver
Prompt
Numeric Key
Key

Assigning Responsibilities

  • After core classes identified, assign responsibilities to classes
    • responsibilities for exhibiting behaviors
    • responsibilities for holding knowledge
  • Write responsibilities on CRC cards for each core class
  • Task of finding collaborators for classes often intermixed with finding responsibilities
  • Use a combination of brainstorming and role-playing of scenarios (see later) to discover responsibilities
  • Focus on the what, not the how. Grady Booch: "When considering the semantics of classes and objects, there is the tendency to explain how things work; the proper response is 'I don't care.'"
    False semantic distinction among responsibilities may rob us of the ability to use inheritance and polymorphism to advantage.

Responsibility Detection Pointers

  1. Brainstorm first. Refine later. Use brainstorming to identify a set of candidate responsibilities for the core classes. Strive for inclusion of relevant responsibilities rather than exclusion. Don't worry about duplication.
    Later refine the lists of responsibilities. Name each carefully.

  2. Think simple. Factor out complexity. If most the responsibilities fall to one or two classes, then the system is probably biased toward a procedural perspective -- does not take advantage of polymorphism and encapsulation. Many of the classes are reduced to "records" -- simply knowing about the information they hold.
    ATM example: A tendency might be to give most of the responsibility to the Account class, which becomes a strong, busy "manager" procedure giving commands to relatively weak, ill-defined "worker" classes. Account is probably too inflexible to be directly reused; the other classes are probably too insignificant to be reused.
    Give each class a distinct role in the system. Strive to make each class a well-defined, complete, cohesive abstraction. Such a class has higher probability of being reused.
    ATM example: Give class Withdrawal the responsibility "Withdraw Funds", making it potentially useful to any other class needing to do a withdrawal. Give class Account the responsibility "Accept Withdrawal", which will, of course, be carried out by collaborating with Withdrawal.
    Factoring out complexity also involves identifying specialized behaviors that occurs repeatedly and, as appropriate, spinning off new classes.
    ATM example: The capturing and responding to user requests might be factored out into a new class Form with a responsibility "ask user for information".

  3. Use abstraction to advantage. Build hierarchies of classes. Abstract the essence of related classes by identifying where they have common responsibilities -- where they do the same thing, but do it differently -- same "what", different "how".
    That is, look for opportunities for the classes to use polymorphism to implement the same responsibility differently.
    The new parent classes may be abstract classes. That is, no actual objects may ever exist of that type. The abstract class exists to link together similar concrete types of objects.
    ATM example: Create an abstract class Transaction that is a superclass for Withdrawal, Deposit, etc. It can have an abstract responsibility "execute a financial transaction", that is implemented differently for each subclass.

  4. Do not marry one solution. Play the field first. Remember that CRC cards are inexpensive and erasable!!
    Do not hesitate to experiment with different configurations of classes or assignments of responsibilities. Changing the CRC cards is easy in the early stages of a project; changing the code later in the project is not easy.

Assigning Collaborations

  • Identify relationships among classes
    • Each class is specialist in some set of knowledge and behaviors
    • Classes must cooperate to accomplish nontrivial tasks
    • Thus collaborations between classes are important
  • Pair collaborations with responsibilities on CRC card
  • Use scenario-based role-play to find and/or test these collaborations
    • Scenario is a system behavior and sequence of system events to realize it
    • Simulating execution enables team to discover responsibilities and collaborations and/or check correctness of those already found
  • Add collaborations when relationships found
    • Identify clients and servers
      Server -- class that provides a resource
      Client -- class that uses a resource
      Server is collaborator of client, not vice versa
      ATM example: In a withdrawal operation, Account is a client of the Withdrawal class
    • Identify hierarchies of classes ATM example: Transaction as superclass of Withdrawal, Deposit, etc.



Hierarchy Identification Tips

  • Explore is-a ("kind-of") relationships. ATM example: Withdrawal is a (kind of) Transaction. Withdrawal is not "part of" Transaction.
  • Name key abstractions.
  • Separate mixed classes where necessary.
  • Place super/subclass sets in hierarchies.
  • Look for reusable behaviors
    • reuse existing patterns and frameworks
    • record new patterns and frameworks for reuse within project or in future

CRC Role Play Steps

  1. Create a list of scenarios for use of the system (i.e., use cases) Use brainstorming
    ATM example: customer withdraws cash
  2. Assign the roles of classes to team members Each member has one or more classes
  3. Rehearse the scenario Execute the scenario with team members announcing what affected classes are doing
  4. Correct CRC card and revise scenario
  5. Repeat above two steps as necessary until rehearsal smooth
  6. Perform final scenario

Developing Role-Play Scenarios

  • First, concentrate on the "must do" scenarios Core behaviors of the system, touch central features of system
    ATM example: customer withdraws cash
  • Next, develop conditional "can do if" scenarios Routine tasks to be carried out under certain conditions
    Tasks to avoid exceptional situations
    Careful about crossing out of system scope
  • Finally, record "might do" scenarios ("abuse cases") to test flexibility Exceptions -- unusual, complex, difficult to handle cases
    Help uncover poor collaborations and clarify system scope (a stress test)
    ATM example: withdrawal with insufficient funds
  • Large systems have perhaps 25 scenarios in "must do" and "can do if" categories Break up if larger

Running an Effective Role Play

  • Stick to the scenario
  • Limit the session time ( <= 2 hours )
  • Use conscious, deliberate problem-solving activities
    1. Warm up
      Prepare every session for effective group work by breaking down inhibitions
      Use games, puzzles, brainteasers, mock brainstorming on "fun" topic.
      Use "go-around" review of activities since last session (use if organizational culture discourages above)
    2. Enactment
      Act out each scenario


    3. Assessment
      Build lists of problems encountered
      Evaluate problems found




Warm-Up Tips

  • Warm-up time is never wasted
  • Warm-up every session
  • Inspire confidence of all members of the team Especially important when team just formed or new member added
  • Don't get too serious, too fast

Scenario Enactment

  • Identify and summarize scenarios to be enacted (session agenda) "must do" first, then "can do if"
  • Assign roles to actors
    distribute CRC cards
    collaborators to different persons
    use domain experts for classes if possible
    rotate assignments from session to session


  • Initiate scenario -- hold up first class ATM example: Start with Customer or BankCard


  • Proceed from responsibility to its collaborators Hold up active card or toss "in play" on the table


  • Watch the action to detect problems


  • When errors discovered
    • correct if minor
    • take notes if complex
    • stop enactment immediately if significant and complex -- go to assessment


  • Avoid unnecessary changes Especially after considerable role play, avoid creating more problems


  • Do enactment-assessment on multiple scenarios per session



by H. Conrad Cunningham

2 comments: