meeting -*- Outline -*- May want to photocopy for the class the POS domain model from Fig 12.9 (p. 176), use cases (pp. 50-53), SSDs (Fig 9.5), and contracts (pp. 185-186). * Design Model: Use-Case Realizations with GRASP Patterns (Larman, Ch 17) This is an extended example of the previous chapter's ideas. ** 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. ------------------------------------------ ** Artifact comments (17.2) *** splitting sequence diagrams per system event When collaboration diagrams are used, there will be one diagram for each system event message. When sequence diagrams are used, it may be possible to fit all system event messages on the same diagram, but that could lead to complex hard-to-read diagrams. They can also be split apart. *** contracts Can also be used if available. Realization ensures that everything described by the postcondition happens. *** caution: the requirements are not perfect Need to continuously engage customers and subject matter experts in review and feedback on the growing system's behavior. Also the domain model will often be incorrect as well. *** conceptual vs. design classes You don't have to match the domain model exactly. e.g., controllers aren't usually in domain model. ** Use-case Realizations for the POS System (17.3) idea is to justify the design based on the principles *** makeNewSale system operation (17.4) look at the contract for this (pp. 185ff and p. 253) Preconditions: none Postconditions: - A new Sale instance s is associated with the Register - the attributes of s are initialized Basic question: who's responsible for doing this? Q: What patterns are relevant? creator, controller, expert Overall, it's handling a system event, so it's more of a controller problem. Since only a few system operations in this iteration, we can use a facade controller, like Register. So we add Register and a method makeNewSale to the design model. Now we go down a level into the working of that method. Q: What things is the Register's makeNewSale method responsible for? See the postconditions Q: What patterns are relevant? creator, expert Who creates the Sale? Register, by creator pattern, since it records the sale. Also that makes the association possible. Now we go down another level, what does the creator of a Sale have to do? it has to initialize itself, i.e., create a collection to start its "knowing" responsibility. Is there more to do? Not if we plan to use a built-in collection in the language *** enterItem (17.5) See the contract again Q: What do we have to do? implement the system operation Q: What patterns are relevant? Controller, Creator, ... By controller use Register again Q: Who does display of output? Since we're not working on the UI, we ignore that part for now. (model-view separation) Just make the information known, don't worry about display at this level, or delegate it to a UI class if know how. Q: Now how does Register's enterItem operation work? Use Creator to assign responsibility for creating a SalesLineItem (to Sale) Parameters for the quantity of items sold have to be passed along... Q: What next? need to get a ProductSpecification from the itemID Advice: start by clearly stating the responsibility. Q: Who should be responsible for knowing how to find a ProductSpecification from an itemID? Q: What patterns apply? Information Expert Look in domain model, see ProductCatalog, so use that in design, give it a method getSpecification(itemID)... Q: Who asks the ProductCatalog for the product specification? both Register and Sale have the information so which promotes lower coupling? Register probably has a permanent connection to the catalog Sale becomes less cohesive if given this responsibility and has higher coupling So give this responsibility to Register (more appropriate for a controller to act as a middle-man). *** endSale (17.6) See the contract again (skip) The task is to modify the isComplete attribute of the Sale Q: What patterns apply? Information Expert, which suggests Sale So give Sale a becomeComplete method Now the use case suggests that at this point the system presents the total to the user (Cashier and customer both). How is this done? Q: Who's responsible for knowing the sale total? Information expert suggests Sale, at a lower level, information experts suggest that the SalesLineItem is the expert for figuring a subtotal, and ProductSpecification for knowing the price. show the interaction diagram for this (fig. 17.11) *** makePayment (17.7) See the contract Q: Who handles this message? Some class has to handle this, let's use Register as our Controller again. Now go down a level to the implementation Q: Who creates the Payment instance? Creator says Register, as it records the payment (as in real world) Creator also says Sale, as it must be associated with the payment. Information Expert says Register has the information. Q: How to decide between these two? Best to look at cohesion and coupling aspects, and possibly at future evolution prospects. Lower coupling through use of Sale to create it, since otw it doesn't need to know about Payment. Q: Who is responsible for knowing all the logged sales and doing the logging? Lowers representational gap to use the domain concept of Store, also needed for its finances. Another possibility, use a "SalesLedger" class (a pure fabrication). SalesLedger may help keep the "Store" cohesive. May also want to add SalesLedger to Domain model, since it's a concept in the domain. Simpler to use Store, which we do here... Q: Who is responsible for knowing the balance? Experts are Sale and Payment, but Payment only knows part, and knowing more increases coupling So give this to Sale (getBalance()). *** 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); // ... } } ------------------------------------------ Q: What should the inital domain object be? Something near the root of the containment or aggregation hierarchy... so that it's creation doesn't create higher coupling. e.g. Store in the POS system Q: Who gets control? either the initial domain object or the user interface code - if it's the domain object, need to send it another message to start running - if it's the UI, pass it the initial domain object, and ignore that at this layer of design Q: how to deal with persistent storage, such as a database? For now, delegate that to the information expert (e.g. ProductCatalog), and stub it out if need be. Q: What are the responsibilities of Store's create method? - create Store, Register, ProductCatalog, and ProductSpecification instances - associate the ProductCatalog with the ProductSpecifications. - associate the Store with the ProductCatalog - associate Store with the Register - associate the Register with the ProductCatalog Note: Multiplicity may differ between the domain model and the design model, for example we only have one register object for the current use case. ** 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 ------------------------------------------ Q: Which of these is better? Think about coupling and cohesion, Note that some coupling from the user interface to the domain is not bad, since the domain is more stable. Principles: UI should not have any domain logic responsibilities. UI should forward requests to domain logic layer. ** Use-case realizations within the UP (17.10) Common to draw class diagrams at the same time as interaction diagrams. Remember, design is supposed to be a small part of each iteration (a few days at most in a few weeks).