By Rick Mercer with help from - PowerPoint PPT Presentation

1 / 31
About This Presentation
Title:

By Rick Mercer with help from

Description:

3 A Car could be given the name of the gas station (Exxon126) as an argument ... Example: Dealer does BettingRound, shuffles cards, maintains Player state, tells ... – PowerPoint PPT presentation

Number of Views:21
Avg rating:3.0/5.0
Slides: 32
Provided by: rickmercer
Category:
Tags: help | mercer | rick

less

Transcript and Presenter's Notes

Title: By Rick Mercer with help from


1
Relationships amongst Objects
  • By Rick Mercer with help from
  • Object-Oriented Design Heuristics
  • Arthur Riel
  • Addison-Wesley, 1996, ISBN 0-201-6338-X

2
Outline
  • Consider six relationships between objects
  • Offer some guidelines for better OO design
  • A few design heuristics
  • Low coupling and high cohesion

3
Relationship Between Objects
  • Object relationships occur when one object
  • sends messages to an instance variables
  • sends a message to another object
  • is passed as an argument in a message
  • creates another object
  • reference is returned from a message
  • stores a referential attribute
  • A reference to an object needed by other objects
  • Example Jukebox stores a reference to a
    JukeboxAccount managed by a JukeboxAccountCollecti
    on object

4
Object A sends message to Object B
  • 1 A uses relationship occurs when one object
    sends a message to another object. Example
  • a listener sends an updateUI() message to a JList
    object
  • private class ButtonListener implements
    ActionListener _at_Override public void
    actionPerformed(ActionEvent event)
  • view.updateUI()
  • The sender (new ButtonListener()) must know the
    receiver's name (view)

5
Example Cars and Gas Stations
  • 2 If a Car "contains" a gas station instance
    variable
  • send a fillUp message to its own gas station
  • this.fillUp(Exxon126)
  • If a Car does not "contain" a gas station
  • how can a Car send a fillUp message?
  • 3 A Car could be given the name of the gas
    station (Exxon126) as an argument
  • // aDispatcher object sends this message
  • carj.fillUp(Exxon126)

6
Other uses relationships
  • 4 Let the car find a gas station on its own
  • Assume map is a global variable everyone knows
  • myGasStation map.getNearestGasStation()
  • myGasStation.fillUp()
  • 5 Whenever a car needs gas, let the car build it
  • It will know the name of the object it creates
  • construct a new one in the Cars fillup method
  • Note the gas station will be destroyed upon exit

7
Who constructs needed objects?
  • What object creates object X?
  • Choose an object B to create an X such that
  • B contains X
  • B closely uses X
  • B has the initializing data for X

8
Referential attribute (can be bad)
  • 6 Store a reference to a gas station that was
    created elsewhere
  • Known to some as a referential attribute
  • This provides access to an entire object that was
    constructed elsewhere
  • The car has a reference needed by someone else
  • Be careful This can lead to incorrect behavior
  • Would be better to have just one instance with a
    global point of reference (Singleton Pattern)

9
Design HeuristicRiel's Heuristic 4.1
  • Minimize the number of objects with which another
    object collaborates
  • Worst case The design has a collection of simple
    objects where each one uses all others
  • Could one class contain several smaller objects?

10
A Meal Class Wrap 3 Smaller Classes
Melon
cost()
Restaurant Patron
cost()
Steak
Meal
Pie
cost()
Melon
cost()
Restaurant Patron
cost()
cost()
Steak
Pie
cost()
11
Meal Wrapper Class
  • Encapsulation makes 4 messages look look one
  • Containment simplifies things
  • RestaurantPatron collaborates with one object
    now, instead of three

12
If you have instance variables, use them
  • Containment implies a relationship, so messages
    should be sent to contained objects
  • If no messages are sent to a contained object, it
    doesn't belong, Put the attribute in the right
    class
  • Exception Container classes
  • ArrayList, HashMap, TreeMap, and so on, may not
    send messages to their elements
  • other than equals or compareTo message
  • Their job is to add, find, and remove elements

13
Don't use too many instance variables
  • Most of the methods in a class should be using
    most of the instance variables most of the time
  • If not, perhaps there should be two classes
  • Classes should not contain more objects than a
    developer can fit in short term memory
  • Maximum should be plus or minus 2 (5 to 9
    instance variables)
  • A heuristic is a rule of thumb, not a rule

14
Contained objects dont talk to their containers
  • A class must know what it contains, but the
    con-tained class should not know who contains it
  • It's okay for a bedroom to know it has a clock,
    but the clock should not be dependent on the
    bedroom
  • CurrentJukeboxAccount should not send messages to
    the Listener that controls an attempt to play.
  • The JukeboxAccountCollection need not know it is
    contained in an instance of Jukebox
  • All contained objects are loosely coupled
  • they are not very dependent on each other

15
Use a Mediator to Coordinate Activities
  • Objects that share lexical scope ? those in the
    same containment ? need not have relationships
    between them
  • Consider an ATM which contains a card reader and
    a display screen
  • The card reader should not send a message to the
    display screen
  • better reuse--could use the card reader software
    for a security entrance without taking the
    display screen

16
Violation Increases Complexity
  • An ATM may contain
  • card reader, display screen, and keypad
  • The ATM should coordinate activities between
    these three objects
  • Dont need to have additional collaborations

ATM
displayPIN()
HaveACard?
getPIN()
Display
Card Reader
Keypad
17
Coupling
  • Coupling A measure of how strongly one class is
    connected to, has knowledge of, or relies upon
    other classes
  • Low coupling the class is not dependent on too
    many other classes--good
  • High Coupling class is dependent on too many
    others--bad
  • A change to one class forces changes in others
  • More difficult to understand a type in isolation
  • Assign responsibilities so that coupling remains
    low

18
Which is the better design?
  • If a POST object records an instance of Payment,
    perhaps the POST object constructs Payment
  • Then POST asks Sale to add the new payment
  • POST is coupled to Payment in the following
    design
  • With this design, POST needs to know 2 classes

makePayment()
1 create()
POST
p Payment
2 addPayment(p)
Sale
19
An alternative design
  • Try associating Payment with Sale
  • In both designs, Sale is coupled to Payment
  • Low coupling favors this 2nd design

makePayment()
1 makePayment()
POST
Sale
1.1. create()
Payment
20
Try to keep coupling low
  • Common forms of coupling
  • Class B has an instance of Class X
  • Class B send a message to an instance of Class X
  • Class B is a subclass of Class X (inheritance)
  • Class B implements interface X
  • So coupling does occur, in any OO program
  • Dangerous case of high coupling
  • Allow one object to use ins. vars. of another type

21
Coupling
  • Hard to say what high coupling is
  • Will have some coupling instance variables, one
    object asks another for help, ...

22
High Cohesion
  • Assign responsibilities so that cohesion remains
    high cohesion consistency, pulling together
  • Cohesion A measure of how strongly related and
    focused the responsibilities of a class are
  • High functional cohesion is good
  • Low cohesion can be bad
  • hard to understand
  • hard to reuse
  • hard to maintain
  • fragile constantly affected by change

23
Reconsider Design
  • In the first design, POST appears to be doing
    little, so this is okay
  • But when POST takes on more tasks, it could get
    bloated and increasingly incohesive
  • Imagine POST doing 20 tasks
  • The design above is a path towards lower cohesion

24
Design 2
  • An alternative assigns the responsibility of
    creating the Payment to Sale, not POST
  • This design supports lower coupling and higher
    cohesion
  • These guidelines shouldn't be considered in
    isolation

25
High vs. Low Cohesion
  • High functional cohesion exists when the elements
    of a class "all work together to provide some
    well-bounded behavior" Grady Booch
  • Examples of low cohesion
  • One class is responsible for many things in
    different functional areas
  • Example Model arranges views, builds menus,...
  • One class has sole responsibility of one complex
    task in one functional area
  • Example Dealer does BettingRound, shuffles
    cards, maintains Player state, tells players what
    to do, ...

26
High Cohesion
  • A class has moderate responsibilities in one
    functional area and collaborates with other
    objects to fulfill tasks
  • Example Dealer coordinates but gets help from
  • a deck of cards that can shuffle and deal cards
  • the player that can figure out what to do next
    and knows what he or she can bet.
  • the view to show the hands and pot
  • Small number of methods, highly related
    functionality, doesn't do too much

27
Benefits of High Cohesion
  • Design is clearer and more easily understood
  • Maintenance (bug fixes, enhancements, changing
    business rules) is easier
  • The fewer classes you touch the better Adele
    Goldberg
  • High cohesion can help you attain lower coupling

28
Information Expert
  • The most basic, general principle of assigning
    responsibilities (behavior/methods) is to
  • Assign the responsibility to the object that has
    the information necessary to fulfill it.
  • That which has the information, does the work.
  • Who decides if the jukebox object can select?
  • Important skill in OO Design
  • Which objects should do what?
  • Find objects
  • Assign responsibilities

29
Role Play a Scenario
  • Jukebox Now I need to determine whether or not
    the current user can play the selected Song. Who
    is responsible for knowing the playing time of
    any Song?
  • Song It seems like I should be responsible for
    knowing the duration of my Song. For example, it
    might take 3 minutes and 34 seconds to be
    completely played. I'll add the responsibility
    knowPlayTime to my CRC card.
  • Jukebox Okay, now I should check to make sure
    the user is able to select this Song before
    telling the CdPlayer to play it. I seem to
    remember I cannot simply play a Song without
    checking on a few things. I know the current
    JukeboxAccount and the selected Song. What do I
    do now?

30
Alternative 1 JukeBox So tell me Song, how
many minutes and seconds do you require to be
played? Song 3 minutes and 34 seconds. JukeBox
JukeboxAccount, do you have 3 minutes and 34
seconds credit? JukeboxAccount I'll be
responsible for maintaining remaining time
credit, so I can answer that, Yes, I have enough
credit. JukeBox JukeboxAccount, have you played
fewer than 2 Songs? JukeboxAccount Yes, I have
not played 2 songs today. JukeBox Okay, now we
can play the Song. Here it is CdPlayer. CdPlayer
Okay JukeBox, I would be willing to tell the
physical CD player to play this Song. Actually, I
have no idea how I am going to do that, but I'll
write a playTrack responsibility on my CRC card
for now as long as you send me the Song to be
played during a playTrack message.
31
  • Alternative 2
  • JukeBox JukeboxAccount, can you play this Song?
  • JukeBoxAccount It feels as though I should be
    responsible for maintaining my own time credit,
    it seems appropriate that I should also know how
    many Songs I've played today. So I should be
    able to do some simple calculations to give you
    the answer you seek. Yes JukeBox, I can play the
    Song you sent me. I'll add these responsibilities
    to my CRC card
  • know how much time credit I have left
  • know how many Songs I've played on this date
  • respond to a message like this
    JukeboxAccount.canSelect(currentTrack)

32
Which Alternative is better?
  • Alternative 1 has a higher degree of coupling"
  • Jukebox needs to know more details about Song and
    JukeBoxAccount
  • There were two different message sends in
    alternative 1 versus a single message send of
    alternative 2 (canSelect)
  • Alternative 2 has better cohesion
  • This means that at least two of the knowledge
    responsibilities necessary to answer a canSelect
    message are closely related

33
Which is the better design?
  • Alternative 1 requires Jukebox to know about the
    internal state of Song and JukeBoxAccount
  • This violates "All data should be hidden within
    its class."
  • Alternative 2 better delegates responsibility
  • Alternative 2 has fewer message sends
  • Here is another OOD guideline to indicate 2 is a
    better design
  • Minimize the number of message sends between a
    class and its collaborators

34
Expert
  • The previous design decision is also supported by
    by Craig Larman
  • Problem
  • Trying to determine who should be responsible for
    some action
  • Solution
  • Assign the responsibility to the information
    expert, which is the class with information
    necessary to fulfill the responsibility

35
Group QuestionCourse scheduling
  • How should we check if a student has the proper
    prerequisites before adding a course given these
    three classes
  • Course
  • description, enrollment limit, prerequisites
  • Student
  • name, address, SS, courses taken
  • CourseOffering
  • course number, schedule, room, registrants
Write a Comment
User Comments (0)
About PowerShow.com