Lecture 5a CRC Cards & Sequence Diagrams (Based on Stevens and Pooley (2006, Section 5.6, Chapters 9, 10), Beck and Cunningham (1989) and Fowler (2004, Chapter 4)) David Meredith d.meredith@gold.ac.uk www.titanmusic.com/teaching/cis224-2007-8.html CIS224 Software Projects: Software Engineering and Research Methods 1 Class-Responsibility-Collaboration (CRC) cards • Not part of UML • Associated with responsibility-driven design (as opposed to data-driven design) – “Identify all the responsibilities of the system and divide between classes before considering the data” • Used for checking that a design is good and refining it • Help with identifying classes and associations • Invented by Ward Cunningham to help programmers not used to OO languages to think in terms of objects – Beck, K. and Cunningham, W. (1989) 'A laboratory for teaching object-oriented thinking'. ACM SIGPLAN Notices, 24(10): 1--6. • Available online here: http://c2.com/doc/oopsla89/paper.html 2 • • The definitive features of an object’s role Procedural designs have processes, data flow and data stores In object designs, each object has a role defined by its – class name – responsibilities – collaborators • Class name – Creates vocabulary for discussing design – Should take time to find just the right set of words • Responsibilities – – – – – – Problems to be solved Solutions will exist in many versions and refinements Provide handles for discussing potential solutions Short phrases containing active verbs Take time to find best expression Responsibilities related to class's operations but stated more generally • e.g., "Maintain data about book" • not "Record name of book", "Record ISBN number of book", "Store number of copies of book", etc. • Collaborators – Objects that will send or receive messages to or from objects of a class while these objects are fulfilling the responsibilities of the class – Therefore a class is associated with all of its collaborators • Therefore CRC cards help with identifying associations and their navigability 3 Using CRC cards Copy Responsibilities Collaborators Inform corresponding Book when borrowed and returned Book • • • • Use physical index cards Each card has three areas Design progresses from knowns to unknowns Walk through use cases and play "what if" – – Maintain data about a particular copy of a book • • Book Responsibilities Collaborators • Maintain data about one book Know whether there are borrowable copies Copy • • • • • • – Collaborators Maintain data about copies borrowed Copy Meet requests to borrow and return copies Copy • add responsibility to an existing class or make a new class with the responsibility Each class usually has no more than three or four responsibilities Too many responsibilities suggests low cohesion If class ends up having too many responsibilities – LibraryMember Responsibilities identify various different scenarios that could arise as discover new responsibilities that have to be fulfilled, decide whether to first see if can re-express responsibilities more concisely then consider sharing responsibilities between two or more classes Avoid premature complexity by concentrating on the immediate needs of the scenario being walked through Team members who suspect weaknesses can suggest scenarios aimed at exposing these weaknesses Expect responsibilities to be revised as CRC cards are used Too many collaborators implies high coupling Note that when walking through use case scenario, actually thinking about how objects 4 interact, not classes Responsibilities on a class diagram LibraryMember -- Maintain data about copies borrowed -- Meet requests to borrow and return copies Copy Responsibilities -- Inform corresponding Book when borrowed and returned -- Maintain data about a particular copy of a book Book -- Maintain data about one book -- Know whether there are borrowable copies • Once CRC cards seem adequate to account for various scenarios of use cases, can make an initial class model – responsibilities can be notated on class icons as comments • Can then translate responsibilities into more detailed operations • Associations can be drawn between each class and its collaborators 5 Refactoring • After building initial class model, might decide that an operation should be in a different class – maybe because this class should not fulfill a particular responsibility – Need to reassign the operation without changing the public behaviour of the system • this is called refactoring • Might find that two classes have overlapping responsibilities – maybe could both be subclasses of a single superclass that fulfills the responsibilities common to both classes • Helps with finding the right abstractions – Helps particularly with finding classes that are not domain classes • Because such classes not mentioned in the requirements specification or use case analyses 6 Interaction diagrams • Use case diagram describes tasks that system must help actors to perform • Class diagram describes classes required to realize use cases and relationships between these classes • Interaction diagrams describe how objects interact to realize the use case scenarios – Can use CRC cards to explore possible interactions and interaction diagrams to record chosen interaction in detail 7 Sequence diagrams • Participants • • A B C Actor • • sync msg 1 sync msg to self sync msg 2 • sync msg 3 return value • • • • Response, return Lifeline Activation, V Activation, X • • • • Sequence diagram shows how actors and objects interact to realize a use case scenario Only shows actors and objects involved in the scenario Each object or actor is called a participant and is represented by an icon in a row across the top of the diagram Extending down the page from each participant is a dashed line called a lifeline Time is understood to move forward as we move down the diagram A message sent from participant A to participant B is represented by an arrow with a solid line drawn from the lifeline of A to the lifeline of B (sync msg 2) If A has to stop computing while B carries out the operation invoked by the message sent to it by A, then this message is said to be synchronous and control is passed from A to B A synchronous message is represented on a sequence diagram by an arrow with a solid black triangular head When B receives the message, it starts to have a new live activation, denoted here by V This activation is represented by drawing a narrow rectangle covering the lifeline of B, starting at the point where the arrow representing the message from A hits the lifeline of B In a procedural interaction (no concurrency), exactly one object is computing at any given instant If B sends a message to another object, C, B may stop computing temporarily while C starts to have a new live activation, X B will continue to have the live activation, V, until it has finished carrying out the operation invoked by the message, sync msg 2, sent to it by A At the end of its activation, B might send a 8 return value to A, indicated by the dashed arrow with the stick head shown Sequence diagrams • Participants • A B C Actor sync msg 1 – This means that most of the message sends are represented by arrows that go from left to right sync msg to self sync msg 2 sync msg 3 • return value • Response, return Lifeline Activation, V Can indicate when an object is computing by shading those periods on the activations For readability, the participants should generally be arranged in the order in which they first participate in the interaction Activation, X • If an object of class A sends a message to an object of class B in a sequence diagram, this implies that there is an association between class A and class B in the class model In procedural systems, only actors can initiate activity by sending a message "out of the blue" System objects can only send messages when they have been made active by receiving a message from another object 9 Sequence diagrams • Participants • A B C Actor sync msg 1 sync msg to self sync msg 2 • sync msg 3 return value • Response, return Lifeline Activation, V Activation, X • At any given instant there will be a stack of live activations and the one at the top of the stack will be the one that currently has control and is computing All the other activated objects are waiting to receive control back from objects to which they have sent messages If the object whose activation is currently at the top of the stack (e.g., B) sends a message, then the object that receives this message (C) becomes active and its activation (X) becomes the top of the stack If the activation X of the object, C, is at the top of the stack and it terminates, then its activation is removed from the stack and control returns to the object B whose message send, sync msg 3, started the activation X The activation V during which sync msg 3 was sent then becomes the new top of the stack Sequence diagrams Participants A B C Actor sync msg 1 sync msg to self sync msg 2 sync msg 3 return value Response, return Lifeline Activation, V • If an object sends a message to itself, then the object gets another new live activation • That is, the object now has two live activations on the stack • Represented on sequence diagram by a nested activation, with activation resulting from message to self slightly offset from older activation Activation, X 11 More advanced features • • Diagram describes process of promoting me to be Head of Department within personnel department database No need to name participant objects and actors – : Lecturer : PersonnelOfficer getName() • n = getName() : "David Meredith" destroy() new HeadOfDepartment(n) Reply message arrow can be labelled with assignment of return value to a variable – • • : HeadOfDepartment Can just precede class of object with a colon to indicate that participant is an object, not a class Actual value returned can be given after colon Object disposal or destruction indicated by a synchronous message sent to the object whose lifeline is terminated with an X Construction of new object indicated by horizontal asynchronous message arrow directly to the head of the new participant – Asynchronous message arrow has stick head • – Synchronous message arrow has solid black triangular head Asynchronous message starts a new thread of control • Participant that sends asynchronous message continues computing 12 after sending message Conditional behaviour theLibraryMember :LibraryMember : BookBorrower theCopy :Copy theBook :Book borrow(theCopy) okToBorrow() canBorrow = okToBorrow() opt [canBorrow == true] beBorrowed(theLibraryMember) copyBorrowed(theCopy) • Different scenarios within a use case can sometimes be represented on same sequence diagram by guarding parts of the interaction with conditions • Conditional behaviour enclosed within rectangle labelled “opt” (for “optional”) • Guard condition written between square brackets near “opt” label 13 Conditional behaviour and loops Found message No object name careful: Distributor :Order ordinary: Distributor for each line item if value > £10000 careful.dispatch else ordinary.dispatch dispatch Loop operator for iteration alt operator for if -else loop alt Sequence diagrams not good at expressing looping and conditionals - very clumsy notation. [for each line item] [value > £10000] Better to express complex looping and conditionals with pseudocode. dispatch Guards (must be mutually exclusive) [else] dispatch Asynchronous message 14 Concurrency and asynchronous calls :Student :PersonalTutor :StudentActor :PersonalTutorActor chooseCourses(m1,...m6) message message confirmChoice(m1,...m6,self) Synchronous message or call Asynchronous message sendEMail Return from earlier message unblocks synchronous message send • In single-threaded, procedural interaction, only one participant computing at any given time and all messages are synchronous – When object sends synchronous message, stops computing and loses control until receiver finishes handling message and returns – Return may be indicated on diagram • In multi-threaded, concurrent interaction, two or more objects computing simultaneously – Some messages may be asynchronous • When object sends asynchronous message, can continue computing and recipient also gets a live activation – generates two concurrent threads 15 Summary • Class-responsibility-collaboration (CRC) cards – Technique for • finding classes and associations • checking that design realizes use cases • Refactoring – Changing responsibilities of a class without changing behaviour of system – Identifying overlapping responsibilities and moving common responsibilities to new superclasses • Interaction diagrams describe how objects interact to realize use cases • Sequence diagrams – – – – – – – participants, lifelines, activations, messages, returns synchronous and asynchronous messages messages to self representing creation and destruction of objects representing return values representing conditionals and loops Asynchronous calls and concurrency 16