Professional Documents
Culture Documents
Object-Oriented Design Principles
Object-Oriented Design Principles
Roadmap
© Oscar Nierstrasz 2
OO Design Principles
Roadmap
© Oscar Nierstrasz 3
OO Design Principles
Motivation
© Oscar Nierstrasz 4
OO Design Principles
© Oscar Nierstrasz 6
OO Design Principles
http://en.wikipedia.org/wiki/Snakes_and_ladders
© Oscar Nierstrasz 7
OO Design Principles
Game rules
> Players
— Snakes and Ladders is played by two to four players, each with her own token
to move around the board.
> Moving
— Players roll a die or spin a spinner, then move the designated number of
spaces, between one and six. Once they land on a space, they have to perform
any action designated by the space.
> Ladders
— If the space a player lands on is at the bottom of a ladder, he should climb the
ladder, which brings him to a space higher on the board.
> Snakes
— If the space a player lands on is at the top of a snake, she must slide down to
the bottom of it, landing on a space closer to the beginning.
> Winning
— The winner is the player who gets to the last space on the board first,
whether by landing on it from a roll, or by reaching it with a ladder.
http://www.ehow.com/facts_5163203_snakes-amp-ladders-rules.html
© Oscar Nierstrasz 8
OO Design Principles
Variations
© Oscar Nierstrasz 9
OO Design Principles
Roadmap
© Oscar Nierstrasz 10
OO Design Principles
Programming is modeling
Players
Everything is an object
© Oscar Nierstrasz 12
OO Design Principles
Computation is simulation
© Oscar Nierstrasz 13
OO Design Principles
Model specialization
© Oscar Nierstrasz 14
OO Design Principles
Roadmap
© Oscar Nierstrasz 15
OO Design Principles
Responsibility-Driven Design
Responsibility-driven
Responsibility-driven design
design ...
... minimizes
minimizes the
the
rework
rework required
required for
for major
major design
design changes.
changes.
—
— Wirfs-Brock,
Wirfs-Brock, 1989
1989
© Oscar Nierstrasz 16
OO Design Principles
Player
•keeps track of where it is
Game
•moves over squares of the
•keeps track of the game state
board
Square Die
•keeps track of any player on it •provides a random
number from 1 to 6
First Square
•can hold multiple players Last Square
•knows it is the winning square
Snake
•sends a player back to Ladder
an earlier square •sends a player ahead to
a later square
© Oscar Nierstrasz 17
OO Design Principles
© Oscar Nierstrasz 18
OO Design Principles
Top-down decomposition
Use concrete scenarios to drive interface design
jack
jack == new
new Player("Jack");
Player("Jack");
jill
jill == new
new Player("Jill");
Player("Jill");
Player[]
Player[] args
args == {{ jack,
jack, jill
jill };
};
Game
Game gamegame == new
new Game(12,
Game(12, args);
args);
game.setSquareToLadder(2,
game.setSquareToLadder(2, 4); 4);
game.setSquareToLadder(7,
game.setSquareToLadder(7, 2); 2);
game.setSquareToSnake(11,
game.setSquareToSnake(11, -6); -6);
assertTrue(game.notOver());
assertTrue(game.notOver());
assertTrue(game.firstSquare().isOccupied());
assertTrue(game.firstSquare().isOccupied());
assertEquals(1,
assertEquals(1, jack.position());
jack.position());
assertEquals(1,
assertEquals(1, jill.position());
jill.position());
assertEquals(jack,
assertEquals(jack, game.currentPlayer());
game.currentPlayer());
game.movePlayer(4);
game.movePlayer(4);
assertTrue(game.notOver());
assertTrue(game.notOver());
assertEquals(5,
assertEquals(5, jack.position());
jack.position());
assertEquals(1,
assertEquals(1, jill.position());
jill.position());
assertEquals(jill,
assertEquals(jill, game.currentPlayer());
game.currentPlayer());
© Oscar Nierstrasz 20
OO Design Principles
Roadmap
© Oscar Nierstrasz 21
OO Design Principles
http://en.wikipedia.org/wiki/Information_hiding
© Oscar Nierstrasz 22
OO Design Principles
© Oscar Nierstrasz 23
OO Design Principles
Encapsulate state
public
public class
class Game
Game {{
private
private List<ISquare>
List<ISquare> squares;
squares;
private
private int
int size;
size; Don't let anyone
private
private Queue<Player>
Queue<Player> players;
players; else play with you.
private
private Player
Player winner;
winner;
...
...
— Joseph Pelrine
}} public
public class
class Player
Player {{
private
private String
String name;
name;
private
private ISquare
ISquare square;
square;
...
...
}}
public
public class
class Square
Square implements
implements ISquare
ISquare {{
protected
protected intint position;
position;
protected
protected Game
Game game;
game;
private
private Player
Player player;
player;
...
...
}}
© Oscar Nierstrasz 24
OO Design Principles
public
public class
class Square
Square implements
implements ISquare
ISquare {{
private
private Player
Player player;
player;
public
public boolean
boolean isOccupied()
isOccupied() {{
return
return player
player !=
!= null;
null;
}}
public
public void
void enter(Player
enter(Player player)
player) {{
this.player
this.player == player;
player;
}}
public
public void
void leave(Player
leave(Player _)
_) {{
this.player
this.player == null;
null;
}}
...
...
}}
© Oscar Nierstrasz 25
OO Design Principles
public
public class
class Player
Player {{
private
private ISquare
ISquare square;
square; Players do not
public
public void
void moveForward(int
moveForward(int moves)
moves) {{
square.leave(this);
need to know all
square.leave(this);
square
square == square.moveAndLand(moves);
square.moveAndLand(moves); the different kinds
square.enter(this);
square.enter(this); of squares …
}} ...
...
}} © Oscar Nierstrasz 26
OO Design Principles
public
public class
class Square
Square implements
implements ISquare
ISquare {{
private
private Player
Player player;
player;
public
public void
void enter(Player
enter(Player player)
player) {{
this.player
this.player == player;
player;
}}
...
...
}} public
public class
class FirstSquare
FirstSquare extends
extends Square
Square {{
private
private List<Player>
List<Player> players;
players;
© Oscar Nierstrasz 28
OO Design Principles
© Oscar Nierstrasz 29
OO Design Principles
Roadmap
© Oscar Nierstrasz 30
OO Design Principles
http://c2.com/cgi/wiki?LotsOfShortMethods
© Oscar Nierstrasz 32
OO Design Principles
Composed Method
© Oscar Nierstrasz 33
OO Design Principles
public
public class
class Game
Game {{
public
public void
void play(Die
play(Die die)
die) {{
System.out.println("Initial
System.out.println("Initial state:
state: "" +
+ this);
this);
while
while (this.notOver())
(this.notOver()) {{
int
int roll
roll == die.roll();
die.roll();
System.out.println(this.currentPlayer()
System.out.println(this.currentPlayer()
+
+ "" rolls
rolls "" +
+ roll
roll ++ ":
": "" +
+ this);
this);
this.movePlayer(roll);
this.movePlayer(roll);
}}
System.out.println("Final
System.out.println("Final state:
state: "" + + this);
this);
System.out.println(this.winner()
System.out.println(this.winner() + + "" wins!");
wins!");
}}
...
...
© Oscar Nierstrasz 34
OO Design Principles
public
public boolean
boolean notOver()
notOver() {{
public
public Player
Player currentPlayer()
currentPlayer() {{
return
return winner
winner ==
== null;
null;
return
return players.peek();
players.peek();
}}
}}
public
public void
void movePlayer(int
movePlayer(int roll)
roll) {{
Player
Player currentPlayer
currentPlayer == players.remove();
players.remove(); //// from
from front
front of
of queue
queue
currentPlayer.moveForward(roll);
currentPlayer.moveForward(roll);
players.add(currentPlayer);
players.add(currentPlayer); //// to
to back
back of
of the
the queue
queue
ifif (currentPlayer.wins())
(currentPlayer.wins()) {{
winner
winner == currentPlayer;
currentPlayer;
}}
}}
public
public Player
Player winner()
winner() {{
return
return winner;
winner;
}}
© Oscar Nierstrasz 35
OO Design Principles
public
public class
class Die
Die {{
static
static final
final int
int MIN
MIN == 1;
1;
static
static final
final int
int MAX
MAX == 6;
6;
public
public int
int roll()
roll() {{
return
return this.random(MIN,MAX);
this.random(MIN,MAX);
}}
public
public int
int random(int
random(int min,
min, int
int max)
max) {{
int
int result
result == (int)
(int) (min
(min ++ Math.floor((max-min)
Math.floor((max-min) ** Math.random()));
Math.random()));
return
return result;
result;
}}
}}
© Oscar Nierstrasz 36
OO Design Principles
• 76 methods
• Most are 1 or 2 LOC
• Average 3.2 LOC
• All methods > 5 LOC
are tests or algorithms
© Oscar Nierstrasz 37
OO Design Principles
Demo
public
public static
static void
void main(String
main(String args[])
args[]) {{
(new
(new SimpleGameTest()).newGame().play(new
SimpleGameTest()).newGame().play(new Die());
Die());
}}
© Oscar Nierstrasz 39
OO Design Principles
Roadmap
© Oscar Nierstrasz 40
OO Design Principles
Program declaratively
public
public class
class Player
Player {{
public
public void
void joinGame(Game
joinGame(Game game)
game) {{
square
square == game.getSquare(1);
game.getSquare(1);
((FirstSquare)
((FirstSquare) square).players().add(this);
square).players().add(this);
}}
...
...
}} public
public class
class Player
Player {{
public
public void
void joinGame(Game
joinGame(Game game)
game) {{
?!
square
square == game.firstSquare();
game.firstSquare();
square.enter(this);
square.enter(this);
}}
...
...
}}
© Oscar Nierstrasz 41
OO Design Principles
public
public class
class Game
Game {{
private
private List<ISquare>
List<ISquare> squares;
squares;
private
private int
int size;
size;
private
private Queue<Player>
Queue<Player> players;
players;
private
private Player
Player winner;
winner;
...
...
}}
public
public class
class Square
Square implements
implements ISquare
ISquare {{
private
private Player
Player player;
player;
public
public void
void enter(Player
enter(Player player)
player) {{
this.player
this.player == player;
player;
}}
...
... public
public class
class FirstSquare
FirstSquare extends
extends Square
Square {{
}} private
private List<Player>
List<Player> players;
players;
public
public void
void enter(Player
enter(Player player)
player) {{
players.add(player);
players.add(player);
}}
...
...
}}
© Oscar Nierstrasz 43
OO Design Principles
Roadmap
© Oscar Nierstrasz 44
OO Design Principles
public
public void
void movePlayer(int
movePlayer(int roll)
roll) {{
...
...
ifif (currentPlayer.square().isLastSquare())
(currentPlayer.square().isLastSquare()) {{
winner
winner == currentPlayer;
currentPlayer;
}}
}}
public
public void
void movePlayer(int
movePlayer(int roll)
roll) {{
...
...
ifif (currentPlayer.wins())
(currentPlayer.wins()) {{
winner
winner == currentPlayer;
currentPlayer;
}}
}}
Tell, don't ask
http://en.wikipedia.org/wiki/Code_smell
© Oscar Nierstrasz 46
OO Design Principles
© Oscar Nierstrasz 47
Safety Patterns
© Oscar Nierstrasz 48
Safety Patterns
© Oscar Nierstrasz 49
OO Design Principles
License
http://creativecommons.org/licenses/by-sa/3.0/
© Oscar Nierstrasz 50