You are on page 1of 31

CSE 403

Object-Oriented Design

Reading:
Object Oriented Design Heuristics Ch. 2-3,
by Authur Riel

These lecture slides are copyright (C) Marty Stepp, 2007. They may not be rehosted, sold, or
modified without expressed permission from the author. All rights reserved.
1
Big questions
 What is a "god class" ?
 What forms can a god class take?
 How do we spot a god class in our system, and how do we get
rid of it?

 What are a "model", "view", and "controller"?


 Why is it beneficial to follow this separation of responsibilities?
 What are some potential problems with controllers?

 What is the "proliferation of classes" problem?


 What does it have to do with "agent" classes?

2
Chapter 2:
Classes and Objects

3
Heuristics 2 quick reference
 Heuristic 2.1: All data should be hidden within its class.
 Heuristic 2.2: Users of a class must be dependent on its public interface, but a
class should not be dependent on its users.
 Heuristic 2.3: Minimize the number of messages in the protocol of a class.
 Heuristic 2.4: Implement a minimal public interface that all classes understand.
 Heuristic 2.5: Do not put implementation details such as common-code private
functions into the public interface of a class.
 Heuristic 2.6: Do not clutter the public interface of a class with items that users of
that class are not able to use or are not interested in using.
 Heuristic 2.7: Classes should only exhibit nil or export coupling with other classes,
that is, a class should only use operations in the public interface of another class or
have nothing to do with that class.
 Heuristic 2.8: A class should capture one and only one key abstraction.
 Heuristic 2.9: Keep related data and behavior in one place.
 Heuristic 2.10: Spin off nonrelated behavior into another class (i.e.,
noncommunicating behavior).
 Heuristic 2.11: Be sure the abstractions that you model are classes and not
simply the roles objects play.

4
OO design pyramid

5
Qualities of modular software
 decomposable
 can be broken down into pieces

 composable
 pieces are useful and can be combined

 understandable
 one piece can be examined in isolation

 has continuity
 reqs. change affects few modules

 protected / safe
 an error affects few other modules 6
Interface and implementation
 public interface: data and behavior of the object that
can be seen and executed externally by "client" code
 private implementation: internal data and methods
in the object, used to help implement the public
interface, but cannot be directly accessed
 client: code that uses your class/subsystem

 Example: radio
 public interface is the speaker, volume buttons, station dial
 private implementation is the guts of the radio; the transistors,
capacitors, voltage readings, frequencies, etc. that user should not
see

7
Some methods should be private!
 Heuristic 2.5: Do not put implementation details such
as common-code private functions into the public
interface of a class.
 Heuristic 2.6: Do not clutter the public interface of a
class with items that users of that class are not able to
use or are not interested in using.

 example: LinkedList class has add and remove methods that


both advance the list to the proper linked node to add/remove,
then performs the operation. How should we design this?

 use a common helper named getNodeAt(int index) that


advances the list to the proper node and returns that node
 make the helper getNodeAt a private method so client code
does not see it and cannot call it
8
Minimizing public interface
 Some ways to minimize a class's protocol:
 Make a method private unless it needs to be public.
 Only supply getters (not setters) for fields' values if you can
get away with it.
 example: Card object with rank and suit (get-only)
 When writing a class that wraps up a data structure, don't
replicate that data structure's entire API; only expose the parts
you absolutely need.
 example: Deck class holds a list of cards, but the game only
shuffles and draws the top card, so rather than having a
getCard(int), add, remove, etc., just have shuffle() and
drawTopCard() methods
 example: If your Game has an inner list or map of Players, supply
just an Iterator or a getPlayerByName(String) method
 Use a Java interface that holds only the needed methods from
the class, and then refer to your class by the interface type in
client code.
9
Cohesion and coupling
 cohesion: how complete and closely related things are
within your class (a good thing)
 coupling: how much classes are connected to /
depend on each other (can be a bad thing)

 Heuristic 2.7: Classes should only exhibit nil or export


coupling with other classes; that is, a class should only use
operations in the public interface of another class or have
nothing to do with that class.

 Heuristic 2.8: A class should capture one and only one key
abstraction.
 (bad) example: PokerGame class that holds all the players, holds an
array representing the card deck, stores all bets and money, does
the logic for each betting round...
10
Reducing coupling
 Some ways to reduce coupling:
 combine two classes that don't represent a whole
abstraction
 example: Bet and Round

 make a coupled class an inner class


 example: list and list iterator
 example: GUI frame and event listener

 provide more unified communication points between


subsystems, so that one subsystem does not need to
communicate with every piece of another subsystem
 example: providing convenience methods (newGame,
reset, ...) in PokerGame class so that GUI does not need to
manually refresh the players, bets, etc.
11
Related data and behavior
 Heuristic 2.9: Keep related data and behavior in one place.
 avoids having to change two places when one change is needed

 example: Should a poker game's Player class remember


whether that player is in the game, what that player's current
bet is, etc? Or should the Game class remember who is in the
game, the Bet class remember every player's current bets, ...?

 Heuristic 2.10: Spin off nonrelated behavior into


another class (i.e., noncommunicating behavior).
 example: code to do save/load of dictionary for anagram game

12
Roles of objects
 Heuristic 2.11: Be sure the abstractions that you
model are classes and not simply the roles objects play.

 example: To model a family tree, should we make classes for


Father, Mother?

 example: Should we make a Club, Diamond, Heart, Spade class


to represent each suit of cards?

 example: Should we make a FirstBetter class that represents


the player who is currently betting first in a card game?

13
Interfaces and inheritance
 interfaces should be used when you want:
 polymorphism: treat different types of objects the same way
 examples: Java's collection framework
 List --> LinkedList, ArrayList; Map --> HashMap,
TreeMap
 Iterator; Comparable

 inheritance should be used when you want:


 code sharing: subclass receives all code from superclass
 substitutability: client code can use a subclass's object in any
situation where a superclass object was expected, and expect the
same results to occur ("Liskov Substitutability Principle")
 example: Java Swing GUI framework's JComponent class
 features: size, color, font; extended by JButton, JPanel, etc.
 any JComponent may be substituted for another in a variety of cases,
such as being added to a frame on the screen 14
Inheritance vs. delegation
 If we write a Stack class that is really just a variation on a List,
should Stack extend List?
 We want a class that models a sorted linked list, so that when any
element is added to the list, it will be added in-order and the list's
contents will always be sorted. Should SortedLinkedList extend
LinkedList?
 We're writing shape classes. Should Square extend Rectangle?

 In all cases, no. List


 We do not want the user to be
Stack
able to arbitrarily call add or +add() List
+remove
remove on the Stack.
remov
 The SortedLinkedList cannot +push
add()
substitute for a normal Stack +pop()
+top()
LinkedList (result of an add +push
differs), so it should not +pop()
extend it. +top()

 Both should delegate to an


inner list data field. 15
Chapter 3:
Topologies

16
Heuristics 3 quick reference
 Heuristic 3.1: Distribute system intelligence horizontally as uniformly as possible,
that is, the top-level classes in a design should share the work uniformly.
 Heuristic 3.2: Do not create god classes/objects in your system. Be very
suspicious of a class whose name contains Driver, Manager, System, or Subsystem.
 Heuristic 3.3: Beware of classes that have many accessor methods defined in their
public interface.
 Heuristic 3.4: Beware of classes that have too much noncommunicating behavior.
 Heuristic 3.5: In applications that consist of an object-oriented model interacting
with a user interface, the model should never be dependent on the interface.
 Heuristic 3.6: Model the real world whenever possible.
 Heuristic 3.7: Eliminate irrelevant classes from your design.
 Heuristic 3.8: Eliminate classes that are outside the system.
 Heuristic 3.9: Do not turn an operation into a class. Be suspicious of any class
whose name is a verb or is derived from a verb, especially those that have only one
piece of meaningful behavior (don't count set, get, print).
 Heuristic 3.10: Agent classes are often placed in the analysis model of an
application. During design time, many agents are found to be irrelevant and should
be removed.

17
"God class" problem
 god class: a class that hoards too much of the data or
functionality of a system. (Not modular!)
 Heuristic 3.1: Distribute system intelligence horizontally as
uniformly as possible, that is, the top-level classes in a design
should share the work uniformly.

 Heuristic 3.2: Do not create god classes/objects in your


system. Be very suspicious of a class whose name contains
Driver, Manager, System, or Subsystem.

 Heuristic 3.4: Beware of classes that have too much non-


communicating behavior, that is, methods that operate on a
proper subset of the data members of a class. God classes
often exhibit much non-communicating behavior.

18
Forms of god classes
 behavioral god class: holds too much logic
 often has a name ending with "System", "Manager"

 data god class: holds too much information


 often has a bunch of access / search methods

19
Eliminating god classes
 Heuristic 3.3: Beware of classes that have many
accessor methods defined in their public interface.
Having many implies that related data and behavior are
not being kept in one place.
 location of "policy" behavior should be in the place where that
policy is enforced / enacted
 lots of accessors are okay on a class with important data that
needs to be shown by a GUI

20
Model and view
 model: classes in your system that are related to the
internal representation of the state of the system
 often part of the model is connected to file(s) or database(s)
 examples (card game): Card, Deck, Player
 examples (bank system): Account, User, UserList

 view: classes in your system that display the state of


the model to the user
 generally, this is your GUI (could also be a text UI)
 should not contain crucial application data
 Different views can represent the same data in different ways
 Example: bar chart vs. pie chart
 examples: PokerPanel, BankApplet

21
Model-view-controller
 model-view-controller (MVC): common design
paradigm for graphical systems
 controller classes connect model and view
 defines how user interface reacts to user input (events)
 receives messages from view (where events come from)
 sends messages to model (tells what data to display)
 sometimes part of view (see left)

data for
rendering
Model View
View
Component
Model updates events
Controller
Controller
22
Advantages of MVC
 decreases coupling
 simplifies complex user interface code
 multiple controllers may be defined based on desired behavior
 changes to part can affect others without requiring the changed
object to know details of others

 increases cohesion
 only the view is concerned with pixels and screen-based data

 improved flexibility
 new views can be added without changing model
 change the feel (Controller) without changing the look (view)

 increases reuse
 one model can be represented in several ways
23
Model-view separation
 Heuristic 3.5: In applications that consist of an object-
oriented model interacting with a user interface, the
model should never be dependent on the interface.
The interface should be dependent on the model.
 (bad) example: Making a system with lots of classes that know
how to render themselves; the GUI just calls card.draw(),
deck.draw(), player.draw().
 GUI should render them, not delegate!

 doesn't this violate Heuristic 2.9: Keep related data and


behavior in one place? Shouldn't things know how to draw
themselves?
 The behavior of drawing things is related to the GUI,
because it is part of the GUI's appearance. So it belongs in
the GUI classes. Having things draw themselves locks them
in to one representation. 24
Misuse of controller classes
 poorly written controller classes contain only behavior
 grabs state from other classes and acts on it
 often has an "-er" or "-or" verb phrase as its name, such as
DataLoader, PasswordChecker
 can be like a behavioral god class on a smaller scale
 design on right below has a controller class
(checking of prereqs could be done by CourseOffering)

25
Misused controllers, cont'd.
 potential problems with controller classes
 data and behavior should be together, not in separate classes
 controller classes are basically the action-oriented paradigm
 difficult to ask a piece of data, "what depends on you?"

 in the real world, people dislike some controllers...


 microwave, radio, car have data and behavior together
 VCR / tape has control separate because controller is expensive

What about a TV? It has remote control separate; why?


 convenience; price; you never want one without the other

 observation: Controllers should be limited and should


not contain important system data or logic.
26
Representing the real world
 Heuristic 3.6: Model the real world whenever possible.
 Example of room heat: fig 3.7 - 3.9, p37-38
 model the room as a way to decide if heat is needed, and to
encapsulate sensors

27
Proliferation of classes
 proliferation of classes: A system that has too many
classes that are too small in size and scope, making the
system hard to use, debug, and maintain
 Heuristic 3.7: Eliminate irrelevant classes from your design.
 irrelevant classes often have only get/set methods

 Heuristic 3.8: Eliminate classes that are outside the system.


 don't model behavior of a blender just because you sell blenders;
don't model a user just because the system is used

 Heuristic 3.9: Do not turn an operation into a class.


 Be suspicious of any class whose name is a verb, especially those that
have only one piece of meaningful behavior. Ask if that piece of
behavior needs to be migrated to some existing or undiscovered class.

28
Agent classes
 What is an "agent class?" Is it good or bad to have
them in your system?

 agent class: a class that acts as a middle-man to


help two or more other classes communicate.
 example: Farmer class to link Cow and Milk classes
 example: Librarian class to link Book and Shelf classes
 Heuristic 3.10: Agent classes are often placed in
the analysis model of an application. During design
time, many agents are found to be irrelevant and
should be removed.
 What defines whether an agent is relevant?
 A relevant agent must have some other behavior beyond
simply being a middle-man; it must have some useful
purpose of its own as well. 29
Is the controller relevant?
 In the model-view-controller paradigm, the controller
acts largely as an agent.
 Should it be there?

Model
business logic

Get Set
Update
State State
Event Change
View
View Controller

model representation user interaction


User
Actions 30
In-class exercise
 In your project groups, define a set of classes and their major
attributes and operations, for a calendar management system.
 Multiple users should be able to use the system to:
 create appointments (either individual or group meetings)
 see an overview of their calendars at various levels of granularity (day,
week, month)
 edit or delete existing appointments
 set reminders to go off for an existing appointment
 Appt. data should be persistent (save and load).

 What classes would you use in this system?


 What model would you use? What data would it contain?
 What views of the model(s) would you want?

 After some time to discuss, we'll do a quick discussion of each


group's design and critique it.
31

You might also like