Information Expert (or Expert)

Similar documents
COMP 6471 Software Design Methodologies

Responsibilities. Using several specific design principles to guide OO design decisions.

Assigning Responsibilities (Patterns of Responsibility Assignment Principles: GRASP)

GRASP: Patterns for. chapter18

Last Time: Object Design. Comp435 Object-Oriented Design. Last Time: Responsibilities. Last Time: Creator. Last Time: The 9 GRASP Patterns

Object Analysis & Design in the textbook. Introduction to GRASP: Assigning Responsibilities to Objects. Responsibility-Driven Design

Assigning Responsibilities by Larman

References: Applying UML and patterns Craig Larman

ADVANCED SOFTWARE DESIGN LECTURE 7 GRASP

ADVANCED SOFTWARE DESIGN LECTURE 4 GRASP. Dave Clarke

Principles of Software Construction: Objects, Design, and Concurrency. Assigning Responsibilities to Objects. toad. Jonathan Aldrich Charlie Garrod

Designing for Visibility & Mapping to Code CSSE 574: Session 4, Part 3

On to Object-oriented Design

CTIS 359 Principles of Software Engineering SOFTWARE DESIGN OO(A)D

Principles of Software Construction: Objects, Design and Concurrency. Object-Oriented Design: Assigning Responsibilities.

2 GRASP Patterns and basic OO Design. Roel Wuyts OASS

Mapping Designs to Code

Introduction to Software Engineering (2+1 SWS) Winter Term 2009 / 2010 Dr. Michael Eichberg Vertretungsprofessur Software Engineering Department of

GRASP Design Patterns A.A. 2018/2019

17. GRASP: Designing Objects with Responsibilities

GRASP ing at the First 5 Patterns Principles CSSE 574: Session 3, Part 4

Object-Oriented Design

Object-Oriented Design

OO Design2. Design Artifacts

Constantinos Constantinides Computer Science and Software Engineering Concordia University Montreal, Canada

Goal: build an object-oriented model of the realworld system (or imaginary world) Slicing the soup: OOA vs. OOD

Operations Contracts and Preliminaries on Design

Logical Architecture & Design Preliminaries

ADVANCED SOFTWARE DESIGN LECTURE 4 SOFTWARE ARCHITECTURE

Introduction to Software Engineering (2+1 SWS) Winter Term 2009 / 2010 Dr. Michael Eichberg Vertretungsprofessur Software Engineering Department of

Creating Class Definitions from Design Class Diagrams: public class SalesLineItem // Java { private int quantity;

CSSE 374: Logical Architecture. Shawn Bohner Office: Moench Room F212 Phone: (812)

Tecniche di Progettazione: Design Patterns

From Design Patterns: Elements of Reusable Object Oriented Software. Read the sections corresponding to patterns covered in the following slides.

From designing to coding

Domain Modeling- 2. Generalization

Software Modeling & Analysis

Patterns and Testing

COMP 6471 Software Design Methodologies

CSSE 374: GRASP ing at the First Five Patterns Principles. Shawn Bohner Office: Moench Room F212 Phone: (812)

Software Engineering

Relationships amongst Objects

Client Code - the code that uses the classes under discussion. Coupling - code in one module depends on code in another module

Domain Modeling. CSSE 574: Week 1, Part 3. Steve Chenoweth Phone: Office (812) Cell (937)

Introduction to Software Engineering (2+1 SWS) Winter Term 2009 / 2010 Dr. Michael Eichberg Vertretungsprofessur Software Engineering Department of

VEL TECH HIGH TECH Dr. RANGARAJAN Dr. SAKUNTHALA ENGINEERING COLLEGE UNIT 1 UML DIAGRAMS

Domain Modeling: Associations and Attributes

Domain Model and Domain Modeling

GRASP 2. CSC 440: Software Engineering Slide #1

What is a Model? Copyright hebley & Associates

On to Object-oriented Design

Some Software Engineering Techniques (Class Diagrams and Pair Programming)

BDSA08 Advanced Architecture

be used for more than one use case (for instance, for use cases Create User and Delete User, one can have one UserController, instead of two separate

Download FirstOODesignPractice from SVN. A Software Engineering Technique: (Class Diagrams)

4 Software models. often more than what people can handle not necessary to know all details at all times

DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING CS2353-OBJECT ORIENTED ANALYSIS AND DESIGN. Unit-I. Introduction to OOAD

Eliminate enterprise software design instability - protect variations! Nickolay Kofanov

Assigning Responsibilities

ROEVER ENGINEERING COLLEGE DEPARTMENT OF INFORMATION TECHNOLOGY CS2353-OBJECT ORIENTED ANALYSIS AND DESIGN. Unit-I. Introduction to OOAD

Review Software Engineering October, 7, Adrian Iftene

Designing a Database -- Understanding Relational Design

Design Engineering. Overview

Object-Oriented Design II - GRASP

OODP Session 4. Web Page: Visiting Hours: Tuesday 17:00 to 19:00

OBJECT ORIENTED ANALYSIS AND DESIGN SYLLABUS

Evolving Software. CMSC 433 Programming Language Technologies and Paradigms Spring Example. Some Motivations for This Refactoring

CSC207H: Software Design Lecture 6

Administrivia. Programming Language Fall Example. Evolving Software. Project 3 coming out Midterm October 28. Refactoring October 14, 2004

OODP Session 5a. Web Page: Visiting Hours: Tuesday 17:00 to 19:00

Inheritance. EEC 521: Software Engineering. Dealing with Change. Polymorphism. Software Design. Changing requirements Code needs to be flexible

CSE 70 Final Exam Fall 2009

Chapter 1: Principles of Programming and Software Engineering

System Sequence Diagrams. Based on Craig Larman, Chapter 10 and Anuradha Dharani s notes

Architectural Models. Section Outline. What is an architectural design? Architecture Types. Example Logical Architecture. Example Deployment Diagram

CS6502-OBJECT ORIENTED ANALYSIS AND DESIGN Two Marks Question with Answers Unit-I Introduction to OOAD

Final Exam CISC 475/675 Fall 2004

Week 5: Background. A few observations on learning new programming languages. What's wrong with this (actual) protest from 1966?

Software Design and Analysis CSCI 2040

Object-Oriented Design I

Object-Oriented Concepts and Design Principles

PART 5 Elaboration Iteration 3 Intermediate topics. Iteration 3

The Software Design Process. CSCE 315 Programming Studio, Fall 2017 Tanzir Ahmed

6.001 Notes: Section 8.1

Principles of Software Construction: Objects, Design, and Concurrency

Object-Oriented Design

OOP Design Conclusions and Variations

18.1 Definitions and General OO Principles

Object- Oriented Design with UML and Java Part I: Fundamentals

Produced by. Design Patterns. MSc in Communications Software. Eamonn de Leastar

Design of Software Systems (Ontwerp van SoftwareSystemen) 2 Basic OO Design. Roel Wuyts

MechEng SE3 Lecture 7 Domain Modelling

PROCESSI DI PRODUZIONE E GESTIONE DEL SOFTWARE. Analysis and Design with UML. Paola Turci

Agile Architecture. The Why, the What and the How

Assertions. Assertions - Example

References: internet notes; Bertrand Meyer, Object-Oriented Software Construction; 10/14/2004 1

SE203b: OO Design for Software Engineers. Office: TEB349, Ext

1: Introduction to Object (1)

Design Pattern- Creational pattern 2015

Object Relationships

Transcription:

Page 2 Page 3 Pattern or Principle? Information Expert (or Expert) Class Responsibility Sale Knows Sale total SalesLineItem Knows line item total ProductDescription Knows product price The GRASP patterns can also be considered as general design principles. Is there a difference? The "Gang of Four" put it this way: One person's pattern is another person's primitive building block. To fulfill the responsibility of knowing and answering the sale s total, three responsibilities were assigned to three design classes. Whether you personally prefer to see it as a pattern or as a principle, the important thing is that you see it! The fulfillment of a responsibility often requires information that is spread across different classes of objects. This implies that there are many partial experts who will collaborate in the task. Page 4 General problem: Who should be responsible for creating a new instance of some class? Page 5 Specific problem: Consider this domain model for the Monopoly example. Assume that there will be a Square class. Which other class should create Square objects?

Page 6 Should Squares be created by some arbitrary class? For example, Dog, Hat or Wheelbarrow? Page 7 Should Squares be created by some arbitrary class? For example, Dog, Hat or Wheelbarrow? Instinctively, this is obviously wrong but why? Page 8 Page 9 Should Squares be created by some arbitrary class? For example, Dog, Hat or Wheelbarrow? Should Squares be created by some arbitrary class? For example, Dog, Hat or Wheelbarrow? Instinctively, this is obviously wrong but why? In fact, most people would suggest that Square should be created by a Board object because a Board contains Squares. The problem is that arbitrary classes have no relationship to Squares.

Page 10 Page 11 With the Monopoly example in mind, let's look at the (GRASP) pattern: Problem: Who should be responsible for creating a new instance of some class? Solution: Assign class B the responsibility to create an instance of class A if at least one of the following is true: B contains or aggregates A objects B records instances of A objects B closely uses A B has the initializing data that will be passed to A when it is created Larman, Figure 17.3 Page 12 Page 13 Sale date time 1 Contains 1..* Sale date time Described-by * 1 Product Description description price itemid Notice that (once again :-) we're examining a domain model here. In the POS application, who should be responsible for creating a SalesLineItem instance? Since a Sale contains many SalesLineItem objects, the pattern suggests that Sale is a good candidate. 1 Contains 1..* SalesLineItem quantity In the POS application, who should be responsible for creating a SalesLineItem instance? SalesLineItem quantity Described-by * 1 Product Description description price itemid Notice that (once again :-) we're examining a domain model here.

Page 14 makelineitem(quantity) create(quantity) Page 15 Aside: Where to Look for Responsibilities By definition, responsibilities are assigned to software objects, not domain objects. Interaction diagrams are therefore a good place to look for inspiration: the messages suggest responsibilities that need to be assigned, and the classes suggest candidates for assignment. but what if the responsibility you're trying to assign belongs to a class that hasn't been designed yet? slineitem In that case, look at the domain model instead. Remember that as much as possible, there should be a close mapping between the domain model and the design, to minimize the representation gap. Note that this assignment of responsibilities requires that a makelineitem method be defined in Sale. Page 16 Page 17 GRASP Patterns We've already seen two GRASP patterns: Information Expert (or just Expert) Coupling is a measure of how strongly one element is connected to, knows about, or relies upon other elements. A class with high coupling depends on many other classes. General principles: There are seven more: Encapsulation reduces coupling. Low coupling is a key element of good design. High Cohesion Polymorphism changes in related classes force local changes Pure Fabrication harder to understand in isolation; need to understand other classes Indirection harder to reuse because it requires additional presence of other classes Protected Variations Design problems caused by high coupling:

Page 18 Page 19 Problem: How to support low dependency, low change impact and increased reuse? Solution: Assign a responsibility so that coupling remains low. Note: is best used to evaluate possible design candidates; if all else is equal, pick the one with the least coupling. Page 20 Bad example how not to do it: Page 21 Bad example how not to do it: Simple fix: move getsquare into the Board class Yes, this example is deliberately contrived. Nobody would actually do something that stupid. :-) Nevertheless, real examples of this type do happen. What's the risk here?

Page 22 Page 23 Yes, this example is deliberately contrived. Nobody would actually do something that stupid. :-) Nevertheless, real examples of this type do happen. Assume we need to create a Payment instance and associate it with the Sale. What class should be responsible for this? What's the risk here? As shown, Dog must know what a collection of Squares looks like. :Payment Thus, if the implementation of Board changes, Dog's getsquare method will break. Page 24 Page 25 :Payment Assume we need to create a Payment instance and associate it with the Sale. What class should be responsible for this? A Register records sales, so suggests that Register is a candidate. 1: create() p:payment 2:addPayment(p) Sale is also coupled to knowledge of a Payment. Register could send an addpayment message to Sale, passing along the new Payment as a parameter.

Page 26 Page 27 1: create() p:payment 2:addPayment(p) Register could send an addpayment message to Sale, passing along the new Payment as a parameter. Either way, Sale and Payment are coupled but that's okay, because they have to be. but this design avoids unnecessary coupling between Register and Payment. 1.1. create() :Payment Sale also coupled to knowledge of a Payment. Page 29 An alternative solution is to have Sale create the Payment. 1: BUT: This assignment of responsibilities couples the Register class to knowledge of the Payment class. Page 28 Some of the places where coupling occurs: attributes: X has an attribute that refers to a Y instance. methods: e.g. a parameter or a local variable of type Y is found in a method of X. inheritance: X is a subclass of Y. types: X implements interface Y. In general, any reference to Y inside X represents coupling. In general, classes that are generic and simple to reuse have low coupling. There will always be some coupling among objects. Otherwise, there would be no collaboration! Note that high coupling isn't always a bad thing. For example, having references in your class to Java library classes isn't a problem, because those classes are always available (at least until you switch to C++ :-). Where high coupling becomes especially bad is when the coupled class is unstable in some way, e.g. one which is under active development and whose interface often changes.

Page 30 High Cohesion Cohesion is a measure of how strongly related and focused the responsibilities of an element are. A class with low cohesion does many unrelated activities or does too much work. A design with low cohesion is fragile, i.e. easily affected by change. Low-cohesion designs are difficult to understand, reuse, and maintain. Page 31 High Cohesion Problem: How to keep complexity manageable? Solution: Assign responsibility so that cohesion remains high. Assume we need to create a Payment instance and associate it with Sale. What class should be responsible for this? Once again, suggests that Register is a candidate. create() p:payment addpayment(p) Page 32 High Cohesion create() p:payment addpayment(p) Assume we need to create a Payment instance and associate it with Sale. What class should be responsible for this? Once again, suggests that Register is a candidate. BUT: Register may become bloated if it is assigned more and more system operations. Page 33 High Cohesion An alternative design delegates the Payment creation responsibility to the Sale, which supports higher cohesion in Register. This design supports high cohesion and low coupling. Note that these two often are found together! create() :Payment

Page 34 High Cohesion varying degrees of functional cohesion: Page 35 varying degrees of functional cohesion: very low cohesion: class responsible for many things in many different areas e.g. a class responsible for interfacing with a data base and remote procedure calls (fix: one class for each area) High Cohesion moderate cohesion: a class has lightweight and sole responsibility for several functional areas that are related to its purpose but not to each other e.g. a class responsible for both the employees of a company and its financial information these are both related to the company, but are not directly related to each other low cohesion: class responsible for a complex task in one functional area e.g. a class responsible for interacting with a relational database high cohesion: class has moderate responsibility in one functional area only e.g. one of several classes which share the responsibility for interacting with a relational database Page 36 High Cohesion Rule of thumb: Page 37 A class with high cohesion has a relative low number of methods, with highly related functionality, and doesn t do much work itself. Modular Design The concept of modular design is much older than objectoriented programming, but it's still a good idea. :-) Modularity is the property of a system that has been decomposed into a set of cohesive and loosely coupled modules Instead, it collaborates and delegates. - Grady Booch, 1994. Note that low (or loose) coupling and high cohesion generally work together each one helps the cause of the other. Likewise, high (or tight) coupling and low cohesion are often found together.

Page 38 Page 39 problem: Beyond the UI layer, what object should be the first to receive and coordinate a system operation? translation: How should the application logic be connected to the UI? presses button : Cashier solution: Assign the responsibility to a class representing one of the following choices: represents the overall system represents a use case scenario in which the system event occurs actionperformed( actionevent ) UI Layer system operation message enteritem(itemid, qty) some POS system event examples: JFrame Domain Layer endsale(), enteritem(), makenewsale(), :??? Larman, Figure 17.21 Page 40 A is an object that is not part of the user interface, and which defines the method for the system operation. Note that classes such as "window", "view", "document", etc. look like controllers, but typically they don't handle system events instead they're at a higher level of abstraction: they receive events and pass them to a controller. s also (should) delegate almost all of their work. The main reason for not allowing a UI object to be a controller is to separate interface from implementation. Page 41 Which class of object should be responsible for receiving this system event message? It is sometimes called the controller or coordinator. It does not normally do the work, but delegates it to other objects. The controller is a kind of "facade" onto the domain layer from the interface layer. Which class should be the controller for enteritem()? enteritem(id, quantity) enteritem(id, quantity) Larman, Figure 17.22 :ProcessSaleHandler

Page 42 Page 43 System Which class should be the controller for enteritem()? endsale() enteritem() makenewsale() Both possibilities are reasonable. Which one is preferable depends on other factors, e.g. coupling and cohesion. makenewreturn() enterreturnitem() system operations discovered during system behavior analysis enteritem(id, quantity) Register endsale() enteritem() makenewsale() makenewreturn() enterreturnitem() allocation of system operations during design, using one facade controller ProcessSale Handler System endsale() enteritem() makenewsale() enteritem(id, quantity) enterreturnitem() makenewreturn() :ProcessSaleHandler Larman, Figure 17.22 Page 44 HandleReturns Handler endsale() enteritem() makenewsale() enterreturnitem() makenewreturn() two possible designs allocation of system operations during design, using several use case controllers Larman, Figure 17.23 Facade (system) controllers are generally best when there aren't too many event types. Page 45 Use case controllers are invariably not domain objects, but instead are purely software objects that have no direct domain analogue (cf. the Pure Fabrication GRASP pattern). Use case controllers are generally best when a Facade controller would suffer from low cohesion or high coupling. Typically the same controller would be used for all events corresponding to different scenarios of the same use case. This makes it possible to maintain state. signs that a controller class is badly designed: There is only one controller class in the system, it receives all event types, and there are many event types. This is a recipe for very low cohesion. The controller itself performs most of the work needed to handle events, rather than delegating. This usually violates the Information Expert pattern (or principle :-), and also leads to low cohesion. Many of the controller's attributes are duplicates of those in other classes. possible fixes: Add more controllers if one is too big and too unfocused. Redesign the controller to delegate as much as possible.

Page 46 Page 47 Larman, Figure 17.8 This is the system sequence diagram for the playgame operation in the Monopoly example. Here's a more detailed look at the same operation, showing the user interface. Which Monopoly class should be the controller? Larman, Figure 17.9 Page 48 Page 49 Let's review the domain model in order to consider possible choices: Based on the domain model, MonopolyGame is the appropriate choice. We need a class which represents a use case, or one which represents the entire system. Larman, Figure 17.10

Page 50 Page 51 This example shows how the UI layer should communicate with the domain layer. presses button : Cashier actionperformed( actionevent ) Larman, Figure 17.11 UI Layer system operation message JFrame 1: enteritem(itemid, qty) A good controller should delegate as much as possible. A bloated controller tries to do too much, and thus has low cohesion. controller Domain Layer 1.1: makelineitem(itemid, qty) Larman, Figure 17.24 Page 52 Page 53 Don't do this! Use Case Realizations A use case realization describes the design for a given use case, in terms of collaborating objects. UML interaction diagrams are used to illustrate use case realizations. Each use case identifies a number of system events (operations). These are shown in system sequence diagrams. The system events become the starting messages that enter the (s) for the domain. For example, for the POS system we have presses button Cashier actionperformed( actionevent ) UI Layer JFrame It is undesirable for an interface layer object such as a window to get involved in deciding how to handle domain processes. The UI shouldn't know that much about the application internals. Business logic is embedded in the presentation layer, which is not useful. System Domain Layer 1: makelineitem(itemid, qty) SaleJFrame should not send this message. Larman, Figure 17.25 makenewsale() enteritem(itemid, quantity) endsale() This is the starting point of the design for this use case!

Page 54 Page 55 Use Case Realizations Use Case Realizations : Register makenewsale, etc., are the system operations from the SSD makenewsale each major interaction diagram starts with a system operation going into a domain layer controller object, such as Register makenewsale Window objects or GUI widget objects or Web control objects enteritem endsale makepayment UI LAYER 1:??? 1:??? create Window objects or GUI widget objects or Web control objects : Register desc = getproductdesc( itemid ) 1:??? DOMAIN LAYER UI LAYER Use Case Realizations We can certainly start with the use cases themselves, but it's probably easier to use contracts if they exist. For example, Contract CO1: makenewsale Operation: makenewsale () Cross References: Use Cases: Process Sale. Pre-conditions: none. Post-conditions: A Sale instance s was created. (instance creation) s was associated with the Register (association formed) Attributes of s were initialized : ProductCatalog enteritem() 1:??? DOMAIN LAYER Larman, Figure 18.2 Page 56 : Sale Larman, Figure 18.3 Page 57 Use Case Realizations enteritem(id, qty) 1: makelineitem() Larman, Figure 18.4 1.1: create() Along with the use case text, the postconditions give us the message interactions that will be needed to satisfy the requirements. slineitem Contract CO2: enteritem Operation: enteritem(itemid: ItemID, quantity: integer) Cross References: Use Cases: Process Sale. Pre-conditions: There is a sale underway.. Post-conditions: A SalesLineItem instance sli was created. (instance creation) []

Page 58 Page 59 Object Design: makenewsale Recall the contract for makenewsale. To design this operation, step one is to choose a. Some possibilities: Contract CO1: makenewsale Operation: makenewsale () Cross References: Use Cases: Process Sale. Pre-conditions: none. Post-conditions: A Sale instance s was created. (instance creation) s was associated with the Register (association formed) Attributes of s were initialized Page 60 Now that we have a, the next step is to consider creation of the Sale object. Store Register POSSystem The pattern suggests that Register is the obvious candidate which shouldn't be surprising, especially if you stop to think what the word 'register' actually means. :-) ProcessSaleHandler ProcessSaleSession When a Sale is created, it will need an empty collection in which to store SalesLineItems. As suggests, Sale itself is the obvious place to create this. In this case, Register will do well enough since there aren't many system operations. Page 61 Object Design: makenewsale Note that the important thing here is not so much the specific diagram, but how we derived it. by and Register creates a Sale by makenewsale create Object Design: makenewsale by, Sale creates an empty collection (such as a List) which will eventually hold SalesLineItem instances create lineitems : List<SalesLineItem> this execution specification is implied to be within the constructor of the Sale instance Larman, Figure 18.6 Object Design: enteritem Now let's look at the full set of postconditions for enteritem: Contract CO2: enteritem Operation: enteritem(itemid: ItemID, quantity: integer) Cross References: Use Cases: Process Sale. Pre-conditions: There is a sale underway.. Post-conditions: A SalesLineItem instance sli was created. (instance creation) sli was associated with the current Sale (association formed) sli.quantity became quantity (attribute modification) sli was associated with a ProductDescription, based on itemid match (association formed)

Page 62 Page 63 Object Design: enteritem Design questions, continued: Design questions: Which class should we use? How to find a ProductDescription? By the same logic as for makenewsale, the should be Register. How to create a new SalesLineItem? The postconditions require that a SalesLineItem be created. The domain model states that a Sale contains SalesLineItems, which suggests that a software Sale object could do likewise. The pattern tells us that it's reasonable for Sale to create the SalesLineItem. Object Design: enteritem Putting everything together, we get this picture: by by enteritem(id, qty) 2: makelineitem(desc, qty) 1: desc = getproductdesc(id) 2.1: create(desc, qty) :Product Catalog by Expert sl: SalesLineItem 1.1: desc = get(id) 2.2: add(sl) : Map<ProductDescription> Larman, Figure 18.7 lineitems : List<SalesLineItem> add the newly created SalesLineItem instance to the List A SalesLineItem needs a ProductDescription to match the incoming itemid. In other words, we must look up the itemid to find the description. Who should be responsible for this lookup? This is a job for Information Expert, which suggests that ProductCatalog is the class which knows about product descriptions so let's design a ProductCatalog class which matches this domain concept, and which contains a getproductdescription method. Who should instigate the ProductDescription lookup? Page 64 Object Design: enteritem Given that ProductCatalog will do the lookup, who should send it the message asking it to do so? It's reasonable to assume that both a Register and a ProductCatalog instance were created at startup (this assumption should be recorded!), so we can safely have the Register assume this responsibility. This implies the concept of visibility, which we'll come back to shortly.