2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented...

33
2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 [email protected] /www-public.telecom-sudparis.eu/~gibson/Teaching/CS Design (In Java) …/~gibson/Teaching/CSC7322/L3-Design(In Java).pdf

Transcript of 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented...

Page 1: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.1

CSC7322: Object Oriented Development

J Paul Gibson, A207

[email protected]

http://www-public.telecom-sudparis.eu/~gibson/Teaching/CSC7322/

Design (In Java)

…/~gibson/Teaching/CSC7322/L3-Design(In Java).pdf

Page 2: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.2

There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies.

—C.A.R. Hoare

DISCUSSION: What is (software) design?

Page 3: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.3

Some reading material on design (in general)

Domain-Driven Design: Tackling Complexity in the Heart of Software, Eric Evans, 2003

Foundations for the Study of Software Architecture, Dewayne E. Perry and Alexander L. Wolf, 1992

A guided tour of program design methodologies, Bergland, Glenn D. , 1981.

On the criteria to be used in decomposing systems into modules, Parnas, David Lorge, 1972

Notes on structured programming. Dijkstra, E.W. , 1970.

The pragmatics of model-driven development, Selic, Bran. 2003

Page 4: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.4

Design: the bridge between the problem and the solution

Discussion: How often does software fail because the design bridge collapses?

Page 5: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.5

Good design is all about experience:

• Recognising a problem’s structure and knowing about alternative solutions (designs) to meeting the requirementsof the problem

• Knowing about implementation issues specific to potential implementation languages/architectures

• Realising that there is often not a perfect fit between the design and the target implementation language/architecture

• Being able to adapt the design to the language and/or adapt the language to the design

Note: in OO we may consider the library to be part of the language

Let us return to the Dice problem with this in mind.

Good judgement is the result of experience … Experience is the result of badjudgement.

—Fred Brooks

Page 6: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.6

From the previous lecture: the Dice problem –

Page 7: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.7

From the previous lecture: the Dice problem –

public interface DiceSpecification extends HasInvariant{

/** * The minimum number of sides for a Dice as specified in the requirements<br> */ final static int MINIMUM_numberOfSides = 3;

/** * The maximum number of sides for a Dice as specified in the requirements */ final static int MAXIMIM_numberOfSides = 36;

/** * The default number of sides for a Dice as specified in the requirements */ final static int DEFAULT_numberOfSides = 6;

Page 8: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.8

From the previous lecture: the Dice problem –

/** * True if the <code> MAXIMIM_numberOfSides </code>, <code>MINIMUM_numberOfSides</code> and * <code> DEFAULT_numberOfSides </code> values for the number of sides of the Dice * are coherent/valid, * otherwise false * @see DiceSpecification#invariant() */ boolean INVARIANT_OF_CLASS = ( MAXIMIM_numberOfSides >= MINIMUM_numberOfSides && MINIMUM_numberOfSides >0 && DEFAULT_numberOfSides >= MINIMUM_numberOfSides && DEFAULT_numberOfSides <= MAXIMIM_numberOfSides);

Page 9: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.9

From the previous lecture: the Dice problem –

/** * Check that the Dice object is in a safe (meaningful) state * * @return true if * <ul> * <li> <ul><li> once the Dice is rolled, the last roll is within range * 1 ... <code> NUMBEROFSIDES </code></li>, or * <li> if the Dice is yet to be rolled then the last roll value is zero, </li> * </ul> and </li> * <li> the <code> numberOfRolls</code> is non-negative, and * </li><li> the number of sides of dice is within range * <code> MINIMUM_numberOfSides </code> ... <code> MAXIMUM_numberOfSides</code> * </li> * </ul> * otherwise false * * @see DiceSpecification#INVARIANT_OF_CLASS */boolean invariant();

Page 10: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.10

From the previous lecture: the Dice problem –

/** * Getter method for <code> NUMBEROFSIDES</code> * * @return the number of sides of the Dice */int numberOfSides();

/** * Getter method for <code> numberOfRolls</code> * * @return the number of times the Dice has been rolled since it was constructed */int numberOfRolls();

/** * Getter method for reading the value of the <code> lastRoll </code><br> * * @return the lastRoll value */int lastRoll ();

Page 11: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.11

From the previous lecture: the Dice problem –

/** * Updates the last roll to a random value between 1 and the number of sides, * and increments the roll count. * * @throws InvariantBroken if Dice is no longer in a safe state */void roll() throws InvariantBroken;

Page 12: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.12

From the previous lecture: the Dice problem –

/** * @return The current state of the Dice as a String<br> * The format to be followed is, eg:<br> * <pre> 6-sided Dice - lastRoll = 1. (Total number of rolls = 10) * </pre> */public String toString();

Page 13: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.13

From the previous lecture: the Dice problem –

/** * @param thing is the Object to test for equality * @return true if * <ul> * <li> the two objects reference the same address, or * <li> the thing is a Dice and there is equality on * <code> lastRoll</code> and <code> NUMBEROFSIDES</code> fields * </ul> * otherwise false */public boolean equals(Object thing);

Page 14: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.14

From the previous lecture: the Dice problem –

/** * @param thing is the Object to test for equality * @return true if * <ul> * <li> the two objects reference the same address, or * <li> the thing is a Dice and there is equality on * <code> lastRoll</code> and <code> NUMBEROFSIDES</code> fields * </ul> * otherwise false */public boolean equals(Object thing);

NOTE: Don’t forget to over-ride the hashCode method –http://javarevisited.blogspot.fr/2011/10/override-hashcode-in-java-example.html

If two objects are equal by equals() method then the result returned by the hashCode() method must be same.

Multiple invocations on same object (that doesnt change state) must return the same result during a single execution; but can differ between executions (!)

Page 15: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.15

From the previous lecture: the Dice problem –

Page 16: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.16

From the previous lecture: the Dice problem –

public abstract class DiceAbstraction implements DiceSpecification{

public boolean equals( Object thing){

if (thing ==null) return false;if ( this == thing) return true;if (! (thing instanceof DiceAbstraction)) return false;

DiceAbstraction that = (DiceAbstraction) thing;return ( (this.lastRoll() == that.lastRoll()) && (this.numberOfSides() == that.numberOfSides()) );}

public String toString(){

String str ="";str = str+ numberOfSides()+"-sided Dice - lastRoll = "+lastRoll()+ ". (Total number of rolls = "+numberOfRolls()+")";return str;}

Page 17: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.17

From the previous lecture: the Dice problem –

/** * Algorithm taken from Josh Bloch's "Effective Java", using primes 37 and 41 * <ul> * <li> initialise with prime = 37</li> * <li> for each field tested in {@link DiceAbstraction#equals} increase * iteratively with another prime multiplier: * hash = 41 * hash + field_integer_value </li> * </ul> * */

public int hashCode(){

int hash = 37; // start with a primehash = 41 * hash + lastRoll(); // iteratively increase with another prime multiplierhash = 41 * hash + numberOfSides();return hash;}

Page 18: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.18

From the previous lecture: the Dice problem –

public boolean invariant(){

return (( (numberOfRolls() == 0 && lastRoll() == 0 ) || (numberOfRolls() > 0 && lastRoll()>0 && lastRoll()<=numberOfSides() ) )&& (numberOfSides()>=MINIMUM_numberOfSides) && (numberOfSides() <= MAXIMIM_numberOfSides) ); }

Page 19: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.19

From the previous lecture: the Dice problem –

Page 20: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.20

From the previous lecture: the Dice problem –

public class Dice extends DiceAbstraction implements DiceSpecification{

// The javadocs are in the code – removed here for easier presentation

public final int NUMBEROFSIDES;

protected Random rng = new Random();

protected static int numberOfDie = 0;

protected int numberOfRolls = 0;

protected int lastRoll = 0;

public boolean invariant(){

return super.invariant() && rng !=null;}

// We saw constructors in previous lecture

Page 21: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.21

From the previous lecture: the Dice problem –

public int lastRoll (){

return lastRoll;}

public int numberOfSides(){return NUMBEROFSIDES;}

public int numberOfRolls(){return numberOfRolls;}

/** * Getter method for the static <code> numberOfDie </code> * @return the number of Die that have been constructed */public static int numberOfDie(){return numberOfDie;}

QUESTION : Why is the static method not specified in the interface or abstract class?

Page 22: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.22

From the previous lecture: the Dice problem –

/** * Setter method for the random number generator local to the dice<br> * * Tested by {@link JUnit_DiceTest#testSetRNGException}, which shows that * we do not need to check invariant as any invalid change to rng is caught * * @param rng is the new random number generator to be used when rolling the dice * @throws IllegalArgumentException if argument <code> rng </code> is <code>null</code> */public void setRNG( Random rng) throws IllegalArgumentException{

if (rng==null) throw (new IllegalArgumentException("Cannot set rng to null"));this.rng = rng;

// if (!invariant()) throw (new InvariantBroken("Dice is no longer in a safe state"));}

/** * Tested by {@link JUnit_DiceAbstractionTest#testRoll}, which guarantees that the Dice is * constructed in a safe state as specified by {@link Dice#invariant}. * */public void roll() throws InvariantBroken{

lastRoll = rng.nextInt(NUMBEROFSIDES)+1; numberOfRolls++;

// if (!invariant()) throw (new InvariantBroken("Dice is no longer in a safe state"));}

Page 23: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.23

From the previous lecture: the Dice problem –

@Beforepublic abstract void setUp() throws Exception;

@Afterpublic abstract void tearDown() throws Exception;

Page 24: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.24

From the previous lecture: the Dice problem –

public class JUnit_DiceTest extends JUnit_DiceAbstractionTest @Beforepublic void setUp() throws Exception {diceDefault = new Dice();diceNonDefaultOK = new Dice((Dice.MAXIMIM_numberOfSides + Dice.MINIMUM_numberOfSides)/2);diceNonDefaultKO = new Dice(Dice.MAXIMIM_numberOfSides + 1);diceRolledTwice = new Dice(); diceRolledTwice.roll(); diceRolledTwice.roll();diceCopyRolledTwice = new Dice ( (Dice) diceRolledTwice);}

Page 25: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.25

From the previous lecture: the Dice problem –

/** * test exception in {@link Dice#setRNG(java.util.Random)} */@Test(expected = IllegalArgumentException.class)public void testSetRNGException() {

((Dice) diceDefault).setRNG(null);}

/** * test {@link Dice#numberOfDie()} by creating 10 new die and checking count */@Testpublic void testNumberOfDie() {

int countNumberOfDie = Dice.numberOfDie();final int NUMBER_OF_DIE_TO_CONSTRUCT = 10;

for (int i=0; i<NUMBER_OF_DIE_TO_CONSTRUCT; i++) new Dice();

Assert.assertEquals(countNumberOfDie+NUMBER_OF_DIE_TO_CONSTRUCT, Dice.numberOfDie());}

Page 26: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.26

From the previous lecture: the Dice problem –

WARNING: All green does not always mean that all is well!

DISCUSSION: Why not?

Page 27: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.27

From the previous lecture: the Dice problem –

Page 28: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.28

From the previous lecture: the Dice problem –

public class Random_DiceTest {

protected static Dice dice = new Dice();

public static void main(String[] args) {

/** * The number of rolls in our simulation */final int NUMBER_OF_TEST_ROLLS = 6;

Random rng = SeedRNGCommandLine.getRandom(args);System.out.println(DateHeader.dateString());System.out.println(dice);dice.setRNG(rng);

System.out.println("Rolling "+NUMBER_OF_TEST_ROLLS+ " times");for (int i =1; i<=NUMBER_OF_TEST_ROLLS;i++){ dice.roll(); System.out.println(i+". Roll = " +dice.lastRoll() );}System.out.println(dice);

} }

Page 29: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.29

From the previous lecture: the Dice problem –

Page 30: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.30

TO DO: Create a new class which adds statistics to the dice

This class should add functionality to store the roll frequencies. You should implement a validation test (as well as running unit tests) as below:

NOTE: Don’t forget to run regression tests

Page 31: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.31

TO DO: Implement 2 different designs

//using inheritancepublic class DiceWithStatistics1 extends Dice implements DiceWithStatisticsSpecification{

}

//using compositionpublic class DiceWithStatistics2 implements DiceWithStatisticsSpecification{

protected Dice dice;}

Page 32: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.32

TO DO: Create 2 different terminal/console views

The frequencies can either be displayed vertically or horizontally.If the frequency values are bigger than the height/width of the screen then you should scale them in order to occupy as much of the screen as possible. The screen size should be stored in constant variables HEIGHT and WIDTH.

1 |********2 |******3 |***4 |****5 |******6 |**7 |***8 |**9 |*****10 |11 |*****12 |**13 |********14 |*****15 |*********10.0 1.0

10.0 * * * * * * * * * * * * * * * * * * * * ** * * * ** * * * ** * * * *** ** ** * * *** ** ** * * *** ***** * * * *** ***** * * * *** ********* ***** ********* ***** ********* ***** ********* ***** ********* *****1.0 --------------- 123456789111111 012345

DISCUSSION:

How to best include these views in the design?

Page 33: 2013: J Paul GibsonTSP: Object Oriented DevelopmentCSC7322/Design.1 CSC7322: Object Oriented Development J Paul Gibson, A207 paul.gibson@telecom-sudparis.eu.

2013: J Paul Gibson TSP: Object Oriented Development CSC7322/Design.33

The consequences of the initial design decision–

Choosing to implement a DiceWithStatistics as a subclass of Dice is a design decision that may have consequencies on later stages of the development.

The alternative re-use mechanism was to design a DiceWithStatistics class/object to have a Dice component class/object. This also may have consequencies on later stages of the development

DISCUSSION: What are the possible consequences (positive and negative)?

CLUE: You may have seen them when we considered the different views

OBSERVERS: We may wish to create different views that automatically update when the state of the models changes