I. From Requirements to Design in This Iteration (Chapter 14) A. did that take weeks? (14.2) B. on to object design (14.3) ------------------------------------------ THE DESIGN MODEL A design model includes: - interaction diagrams - design-level class diagrams Use: - principles of responsibility assignment - design patterns ------------------------------------------ II. Interaction Diagram Notation (Larman Ch 15, Fowler Ch 5) A. preview ------------------------------------------ INTERACTION DIAGRAMS (Larman Ch 15, Fowler Ch. 5) Used to illustrate object designs. Types: - sequence diagrams simpler, clearly shows time sequence easier for computers to draw - collaboration diagrams good for branching, iteration best for hand drawing ------------------------------------------ B. notational highlights ------------------------------------------ NOTATIONAL GOTCHAS Things to watch out for: instances are underlined start with a colon |-----------| | :PMSD | (should be underlined) |-----------| classes are not underlined, no colon |-----------| | Math | (not underlined) |-----------| multiobjects (collections) have double boxes |-----------| |-----------| | | :File |-| (should be underlined) |-----------| ------------------------------------------ C. Example collaboration diagram ------------------------------------------ EXAMPLE COLLABORATION DIAGRAM (15.2) | | makePayment(cashTendered) | | | v | |-----------| | :Register | |-----------| | | 1: makePayment(cashTendered) | | | v | |-----------| | :Sale | |-----------| | | | 1.1: create(cashTendered) | | | v | |------------| | :Payment | |------------| ------------------------------------------ III. GRASP: Designing Objects with Responsibilities (Larman, Ch 16) A. responsibilities and methods (16.1) ------------------------------------------ RESPONSIBILITIES (16.1) Def: A responsibility is "a contract or obligation". Two basic types of responsibilities an object may have: A. doing - something by itself: creating objects, calculating - telling others to do something initiating action coordinating activities B. knowing - some private data - about related objects - about things it can calculate ------------------------------------------ Is a responsibility the same thing as a method? B. Patterns (16.3) ------------------------------------------ DESIGN PATTERNS (16.3) Def: a design pattern is a named problem/solution pair that can be applied in new contexts, with advice on how to apply it, and discussion of its trade-offs. ------------------------------------------ C. GRASP Patterns (16.4) 1. Information Expert (16.6) ------------------------------------------ INFORMATION EXPERT (16.6) Problem: How should one assign responsibilities to objects? Solution: Assign a responsibility to the information expert -- the class that has the information necessary to fulfill the responsibility. Example: In the POS system, Who should be responsible for knowing the total of a sale? By Information Expert we should look for a class of objects that has the information needed. ------------------------------------------ Where do we look for classes that have information? What information is needed to determine the grand total? what information is needed to determine the line item subtotal? What information is needed to determine the product price? What responsibilities did we assign? ------------------------------------------ INFORMATION EXPERT (CONTINUED) Discussion: Information Expert is a frequently used guiding principle. Many partial experts that collaborate. All objects are "alive" or "smart" Should avoid having a single "god class" with many "dumb" objects doing its will. Contraindications: avoid if causes problems with coupling and cohesion. For example, who should the responsible for saving a Sale in a database? Instead design faor separation of major concerns (information hiding). Benefits: - Information hiding, hence low coupling. - Behavior spread out, encouraging more cohesive lightweight classes. Related: - Low Coupling - High Cohesion A.K.A: "Place responsibilities with data", "Do it Myself", ... ------------------------------------------ what examples are there in your designs? 2. Creator (16.7) ------------------------------------------ CREATOR (16.7) Problem: who should be responsible for creating new instances of some class? Solution: Assign class B responsibility for creating an instance of class A if: - B aggregates objects of class A - B contains A objects - B records instances of A objects - B closely uses A objects - B has the initializing data needed to create A objects If more than one applies, prefer a class that aggregates or contains A objects. Example: In the POS system, who should be responsible for creating a SalesLineItem instance? ------------------------------------------ What class is like that in the domain model? ------------------------------------------ Discussion: The basic idea is to find a creator that needs to be connected to the created object anyway. This supports low coupling. Contraindications: if the creation is complex, then use the Factory pattern. Benefits: - low coupling Related Patterns: - Low Coupling - Factory - Whole-Part ------------------------------------------ what examples are there in your designs? 3. Low Coupling (16.8) ------------------------------------------ LOW COUPLING (16.8) Problem: How to support low dependency, low change impact, and increased reuse? Solution: Assign a responsibility so that classes aren't strongly connected. "Coupling" is a measure how strongly one element is connected to, has knowledge of, or relies on other elements. High coupling causes: - changes to affect other classes - difficulty in understanding classes (in isolation) - difficulty in reuse, because more classes are needed Example: Who should create a Payment instance and associate it with a Sale? ------------------------------------------ Which design has lower coupling? ------------------------------------------ Discussion: Low Coupling is an evaluative principle that applies when considering all design decisions. Common forms of coupling X to Y include - X has an attribute of Y - X calls methods of Y objects - X has a method that uses Y e.g., as a parameter, local variable, return type - X is a subclass of Y - X implements the interface Y Low coupling reduces impact of changes. A subclass is strongly coupled to its superclass(es). There will usually be some coupling, just need to gauge it, and understand it. But don't couple strongly with unstable elements. Reusable classes should have low coupling. Contraindications: high coupling to stable elements (the programming language, libraries) is okay. Don't spend extra time "future proofing". Focus on realistic points of high instability or evolution. Benefits: - not affected by other's changes - simple to understand in isolation - convenient to reuse Related Patterns: - Protected Variation ------------------------------------------ what examples are there in your designs? 4. High Cohesion (16.9) ------------------------------------------ HIGH COHESION (16.9) Problem: How to keep complexity manageable? Solution: Assign a responsibility so that cohesion remains high. Functional cohesion is a measure of how strongly related and focused the responsibilities of an element are. A class with low cohesion does many unrelated things, or too much work. This causes classes to be - hard to comprehend - hard to reuse - hard to maintain - delicate; often affected by change Example: Who should create a Payment instance and associate it with a Sale? ------------------------------------------ ------------------------------------------ Discussion: This also applies to methods, subsystems, etc., not just classes. It is an evaluative principle, and should be considered all the time. A rule of thumb is that a class with high cohesion has relatively few methods, with highly related functionality. ------------------------------------------ ------------------------------------------ Contraindications: - simplify maintenance for non OO folk - performance in distributed settings Benefits: - clarity and ease of comprehension - maintenance and enhancement easier - low coupling is often supported - easier to reuse ------------------------------------------ what examples are there in your designs? 5. Controller (16.10) ------------------------------------------ CONTROLLER (16.10) Problem: Who should be responsible for handling an input system event? An input system event is generated by an external actor. The UI turns these into system operations in the application layer. Solution: Assign the responsibility for receiving or handling a system event to a class that: - represents the overall system, device, or subsystem (facade controller), or - represents a use case scenario (use-case or session controller). ------------------------------------------ ------------------------------------------ A controller is a non-UI object responsible for handling a system event. Example: In the POS system, who should handle system events such as enterItem? ------------------------------------------ ------------------------------------------ Discussion: A Controller is a facade that hides details of the domain layer (from the UI layer). Use a use-case controller if - state info must be kept between system events, - to identify out-of-sequence events, - if there are not "too many" kinds of system events A controller should delegate instead of doing the work itself. ------------------------------------------ Why is it bad for the user interface to have responsibility for handling system events? ------------------------------------------ Benefits: - separates application logic from UI leading to higher reuse - allows reasoning about state of interaction in a use-case Related Patterns: - Command, for message handling systems each message is a command object - Facade, a controller is a Facade - Layers - Pure Fabrication, controllers aren't part of domain model ------------------------------------------ what examples are there in your designs? D. Object Design and CRC cards (16.11) ------------------------------------------ CRC CARDS (16.11) An index card for each design class: |------------------------------------| | Sale Collaborators | |------------------------------------| | Knows total SalesLineItem| | Aggregates SalesLineItems | | ... | |------------------------------------| Can use them to play out scenarios - pick up cards when active ------------------------------------------ IV. Design Model: Use-Case Realizations with GRASP Patterns (Larman, Ch 17) A. Use-Case Realizations (17.1) ------------------------------------------ USE-CASE REALIZATIONS (17.1) Relationships: - Use-cases suggest the system events shown in system sequence diagrams. - Details optionally given in contracts. - System events represent initial messages in interaction diagrams. - Interaction diagrams show messages sent among classes inspired by domain model. ------------------------------------------ B. Artifact comments (17.2) 1. splitting sequence diagrams per system event 2. contracts (optional) 3. caution: the requirements are not perfect 4. conceptual vs. design classes C. Use-case Realizations for the POS System (17.3) 1. makeNewSale system operation (17.4) What patterns are relevant? What things is the Register's makeNewSale method responsible for? What patterns are relevant? 2. enterItem (17.5) What do we have to do? What patterns are relevant? Who does display of output? Now how does Register's enterItem operation work? What next? Who should be responsible for knowing how to find a ProductSpecification from an itemID? What patterns apply? Who asks the ProductCatalog for the product specification? 3. endSale (17.6) What patterns apply? Who's responsible for knowing the sale total? 4. makePayment (17.7) Who handles this message? Who creates the Payment instance? How to decide between these two? Who is responsible for knowing all the logged sales and doing the logging? Who is responsible for knowing the balance? 5. startUp ------------------------------------------ THE START-UP DESIGN (17.8) Leave the initialization design for last. Record notes on that has to be done as you design the rest of the system. Common design idiom: - create an initial domain object - it's responsible for creation of other domain objects. E.g., public class Main { public static void main(String[] args) { // create initial domain objects Store store = new Store(); Register register = store.getRegister(); // start up the UI ProcessSaleJFrame frame = new ProcessSaleJFrame(register); // ... } } ------------------------------------------ What should the inital domain object be? Who gets control? how to deal with persistent storage, such as a database? What are the responsibilities of Store's create method? D. Connecting the User Interface Layer to the Domain Layer (17.9) ------------------------------------------ CONNECTING THE UI AND DOMAIN LAYERS (17.9) How does the UI get access to domain objects? - An initial method (e.g., main), creates the domain object and the UI object, and passes the domain object to the UI object - The UI retrieves the domain object from a well-known source (e.g., a factory object) How does the UI get information to display, etc.? - Ask a facade object for it - Get a domain object from the facade, and ask that directly - Register for events with domain objects How does the UI know when to do display? - Tracks state of system - Facade object tells it - Waits for events from domain objects ------------------------------------------ Which of these is better? E. Use-case realizations within the UP (17.10) V. Design Model: Determining Visibility (Larman Ch. 18) A. visability between objects (18.1) When is visibility necessary? So if a Register sends messages to a ProductCatalog, which must be visible to which? B. Visibility (18.2) ------------------------------------------ KINDS OF VISIBILITY Object B is visible to A if: - attribute visibility - parameter visibility - local visibility - global visibility ------------------------------------------ Which would you use if you wanted a relatively permanent connection? which would you use if you didn't want a permanent connection? how would you create a local visibility? how would you achieve a global visibility? VI. Creating Design Class Diagrams (DCDs) (Larman Ch. 19, Fowler Ch. 4) A. When to create DCDs (19.1) B. Example DCD (19.2) ------------------------------------------ EXAMPLE DESIGN CLASS DIAGRAM (DCD) |------------------------| | Register | |------------------------| | | |------------------------| | endSale() | | enterItem(ItemID, int) | | makePayment(Money) | |------------------------| | 1 | | Captures | | | 1 v |-----------------------| | Sale | |-----------------------| | date : Date | | isComplete: boolean | | time: Time | |-----------------------| | makeLineItem( | | ProductSpecification,| | int) | |-----------------------| ------------------------------------------ C. differences from domain model (19.4) What are the differences from deisgn model class diagram? D. Creating a NextGen POS DCD 1. adding method names 2. method name issues a. constructors b. accessing methods (get and set methods) c. multiobjects (collections/containers) d. adding type information e. heading associations and navigability Since Store creates Register, which direction does navagation go on the "Houses" association? Why is there an association from Register to ProductCatalog? f. adding dependency relationships E. Notation for member details (19.6) F. DCDs and Case Tools (19.7) VII. Implementation Model: Mapping Designs to Code (Chapter 20) A. Programming and the Developement Process (20.1) B. Mapping Designs to Code (20.2) 1. Creating class definitions (20.3) 2. Add reference attributes ------------------------------------------ ADDING REFERENCE ATTRIBUTES |------------------------| | Register | |------------------------| | | |------------------------| | endSale() | | enterItem(ItemID, int) | | makePayment(Money) | |------------------------| | 1 | | Captures | | | 1 v |-----------------------| | Sale | |-----------------------| | date : Date | | isComplete: boolean | | time: Time | |-----------------------| | makeLineItem( | | ProductSpecification,| | int) | |-----------------------| Suggests that Register have a Sale field: public class Register { private Sale capturedSale; ... } ------------------------------------------ 3. mapping attributes We have both date and time attributes in Sale, but Java has a built-in class Date that holds both, so what should we use for a field in a Java implementation? 4. creating methods from interaction diagrams (20.4) ------------------------------------------ public class Register { private ProductCatalog catalog; private Sale sale; public enterItem(ItemID id, int qty) { ProductSpecification spec = catalog.getSpecification(id); sale.makeLineItem(spec, qty); } // ... } public class Sale { private ArrayList lineItems = new ArrayList(); public makeLineItem( ProductSpecification spec, int qty) { lineItems.add( new SalesLineItem(spec, qty)); } // ... } ------------------------------------------ 5. Container/Collection Classes in Code ------------------------------------------ import java.util.HashMap; public class ProductCatalog { private HashMap map = new HashMap(); public ProductSpecification getSpecification(ItemId id) { ProductSpecification ret = (ProductSpecification)map.get(id); if (id != null) { return id; } else { // no errors this iteration System.err.println( "got bad product id"); System.exit(1); } } } ------------------------------------------ C. Order of implementation (20.8) What order would you implement the classes for the POS system in? Which ones could happen in parallel? If you implemented from top down, what stubs would you have to write? D. Test-first programming (20.9) E. example listings (see section 20.11)