Title: By Rick Mercer with help from
1Relationships amongst Objects
- By Rick Mercer with help from
- Object-Oriented Design Heuristics
- Arthur Riel
- Addison-Wesley, 1996, ISBN 0-201-6338-X
2Outline
- Consider six relationships between objects
- Offer some guidelines for better OO design
- A few design heuristics
- Low coupling and high cohesion
3Relationship 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
4Object 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)
5Example 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)
6Other 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
7Who 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
8Referential 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)
9Design 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?
10A Meal Class Wrap 3 Smaller Classes
Melon
cost()
Restaurant Patron
cost()
Steak
Meal
Pie
cost()
Melon
cost()
Restaurant Patron
cost()
cost()
Steak
Pie
cost()
11Meal Wrapper Class
- Encapsulation makes 4 messages look look one
- Containment simplifies things
- RestaurantPatron collaborates with one object
now, instead of three
12If 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
13Don'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
14Contained 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
15Use 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
16Violation 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
17Coupling
- 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
18Which 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
19An 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
20Try 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
21Coupling
- Hard to say what high coupling is
- Will have some coupling instance variables, one
object asks another for help, ...
22High 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
23Reconsider 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
24Design 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
25High 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, ...
26High 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
27Benefits 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
28Information 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
29Role 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?
30Alternative 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)
32Which 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
33Which 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
34Expert
- 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
35Group 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