Composition Part 2 1 Class Invariants class invariant

  • Slides: 47
Download presentation
Composition (Part 2) 1

Composition (Part 2) 1

Class Invariants class invariant some property of the state of the object that is

Class Invariants class invariant some property of the state of the object that is established by a constructor and maintained between calls to public methods in other words: the constructor ensures that the class invariant holds when the constructor is finished running every public method ensures that the class invariant holds when the method is finished running 2 the invariant does not necessarily hold while the constructor is running the invariant does not necessarily hold while the method is running

Period Class adapted from Effective Java by Joshua Bloch available online at http: //www.

Period Class adapted from Effective Java by Joshua Bloch available online at http: //www. informit. com/articles/article. aspx? p=31551&seq. Num=2 we want to implement a class that represents a period of time a period has a start time and an end time 3 end time is always after the start time (this is the class invariant)

Period Class we want to implement a class that represents a period of time

Period Class we want to implement a class that represents a period of time 4 has-a Date representing the start of the time period has-a Date representing the end of the time period class invariant: start of time period is always prior to the end of the time period

Period Class 2 Period Date Period is a composition of two Date objects 5

Period Class 2 Period Date Period is a composition of two Date objects 5

public final class Period { private Date start; private Date end; /** * @param

public final class Period { private Date start; private Date end; /** * @param start beginning of the period. * @param end of the period; must not precede start. * @throws Illegal. Argument. Exception if start is after end. * @throws Null. Pointer. Exception if start or end is null */ public Period(Date start, Date end) { if (start. compare. To(end) > 0) { throw new Illegal. Argument. Exception("start after end"); } this. start = start; this. end = end; } 6

Test Your Knowledge 1. 2. 3. Is Date mutable or immutable? Is Period implementing

Test Your Knowledge 1. 2. 3. Is Date mutable or immutable? Is Period implementing aggregation or composition? Add 1 more line of client code to the following that shows how the client can break the class invariant: Date start = new Date(); Date end = new Date( start. get. Time() + 10000 ); Period p = new Period( start, end ); 4. 7 Fix the constructor.

/** * @return the start Date of the period */ public Date get. Start()

/** * @return the start Date of the period */ public Date get. Start() { return this. start; } /** * @return the end Date of the period */ public Date get. End() { return this. end; } 8

Test Your Knowledge Add 1 more line of client code to the following that

Test Your Knowledge Add 1 more line of client code to the following that shows how the client can break the class invariant using either of the start or end methods 1. Date start = new Date(); Date end = new Date( start. get. Time() + 10000 ); Period p = new Period( start, end ); 9

/** * Creates a time period by copying another time period. * @param other

/** * Creates a time period by copying another time period. * @param other the time period to copy */ public Period( Period other ) { this. start = other. start; this. end = other. end; } 10

Test Your Knowledge What does the following program print? 1. Date start = new

Test Your Knowledge What does the following program print? 1. Date start = new Date(); Date end = new Date( start. get. Time() + 10000 ); Period p 1 = new Period( start, end ); Period p 2 = new Period( p 1 ); System. out. println( p 1. get. Start() == p 2. get. Start() ); System. out. println( p 1. get. End() == p 2. get. End() ); 2. Fix the copy constructor. Date does not provide a copy constructor. To copy a Date object d: Date d = new Date(); Date d. Copy = new Date( d. get. Time() ); 11

/** * Sets the start time of the period. * @param new. Start the

/** * Sets the start time of the period. * @param new. Start the new starting time of the period * @return true if the new starting time is earlier than * the current end time; false otherwise */ public boolean set. Start(Date new. Start) { boolean ok = false; if ( new. Start. compare. To(this. end) < 0 ) { this. start = new. Start; ok = true; } return ok; } 12

Test Your Knowledge Add 1 more line of client code to the following that

Test Your Knowledge Add 1 more line of client code to the following that shows how the client can break the class invariant 1. Date start = new Date(); Date end = new Date( start. get. Time() + 10000 ); Period p = new Period( start, end ); p. set. Start( start ); 2. 13 Fix the accessors and set. Start.

Privacy Leaks a privacy leak occurs when a class exposes a reference to a

Privacy Leaks a privacy leak occurs when a class exposes a reference to a non-public field (that is not a primitive or immutable) given a class X that is a composition of a Y public class X { private Y y; // … } these are all examples of privacy leaks 14 public X(Y y) { this. y = y; } public X(X other) { this. y = other. y; } public Y get. Y() { return this. y; } public void set. Y(Y y) { this. y = y; }

Consequences of Privacy Leaks a privacy leak allows some other object to control the

Consequences of Privacy Leaks a privacy leak allows some other object to control the state of the object that leaked the field the object state can become inconsistent 15 example: if a Credit. Card exposes a reference to its expiry Date then a client could set the expiry date to before the issue date

Consequences of Privacy Leaks a privacy leak allows some other object to control the

Consequences of Privacy Leaks a privacy leak allows some other object to control the state of the object that leaked the field it becomes impossible to guarantee class invariants 16 example: if a Period exposes a reference to one of its Date objects then the end of the period could be set to before the start of the period

Consequences of Privacy Leaks a privacy leak allows some other object to control the

Consequences of Privacy Leaks a privacy leak allows some other object to control the state of the object that leaked the field composition becomes broken because the object no longer owns its attribute 17 when an object “dies” its parts may not die with it

Recipe for Immutability the recipe for immutability in Java is described by Joshua Bloch

Recipe for Immutability the recipe for immutability in Java is described by Joshua Bloch in the book Effective Java* 1. 2. 3. 4. 5. Do not provide any methods that can alter the state of the object when we talk Prevent the class from being extended revisit about inheritance Make all fields final Make all fields private Prevent clients from obtaining a reference to any revisit when we talk mutable fields about composition 18 *highly recommended reading if you plan on becoming a Java programmer

Immutability and Composition why is Item 5 of the Recipe for Immutability needed? 19

Immutability and Composition why is Item 5 of the Recipe for Immutability needed? 19

Collections as Attributes Still Aggregation and Composition 20

Collections as Attributes Still Aggregation and Composition 20

Motivation often you will want to implement a class that has-a collection as an

Motivation often you will want to implement a class that has-a collection as an attribute a university has-a collection of faculties and each faculty has-a collection of schools and departments a molecule has-a collection of atoms a person has-a collection of acquaintances from the notes, a student has-a collection of GPAs and hasa collection of courses a polygonal model has-a collection of triangles* *polygons, actually, but triangles are easier to work with 21

What Does a Collection Hold? a collection holds references to instances it does not

What Does a Collection Hold? a collection holds references to instances it does not hold the instances Array. List<Date> dates = new Array. List<Date>(); Date d 1 = new Date(); Date d 2 = new Date(); Date d 3 = new Date(); dates. add(d 1); dates. add(d 2); dates. add(d 3); 100 client invocation dates 200 d 1 500 d 2 600 d 3 700. . . 200 Array. List object 500 600 700 22

Test Your Knowledge What does the following print? 1. Array. List<Point> pts = new

Test Your Knowledge What does the following print? 1. Array. List<Point> pts = new Array. List<Point>(); Point p = new Point(0. , 0. ); pts. add(p); p. set. X( 10. 0 ); System. out. println(pts. get(0)); 2. 23 Is an Array. List<X> an aggregation of X or a composition of X?

Student Class (from notes) a Student has-a string id a Student has-a collection of

Student Class (from notes) a Student has-a string id a Student has-a collection of yearly GPAs a Student has-a collection of courses 1 List<Double> 1 Student gpas 4 Double 24 1 id String Set<Course> courses * Course

Polygonal. Model Class a polygonal model has-a List of Triangles implements Iterable<Triangle> aggregation allows

Polygonal. Model Class a polygonal model has-a List of Triangles implements Iterable<Triangle> aggregation allows clients to access each Triangle sequentially class invariant List never null 1 Polygonal. Model List<Triangle> tri * Triangle 25

Iterable Interface implementing this interface allows an object to be the target of the

Iterable Interface implementing this interface allows an object to be the target of the "foreach" statement must provide the following method Iterator<T> iterator() Returns an iterator over a set of elements of type T. 26

Polygonal. Model class Polygonal. Model implements Iterable<Triangle> { private List<Triangle> tri; public Polygonal. Model()

Polygonal. Model class Polygonal. Model implements Iterable<Triangle> { private List<Triangle> tri; public Polygonal. Model() { this. tri = new Array. List<Triangle>(); } public Iterator<Triangle> iterator() { return this. tri. iterator(); } 27

Polygonal. Model public void clear() { // removes all Triangles this. tri. clear(); }

Polygonal. Model public void clear() { // removes all Triangles this. tri. clear(); } public int size() { // returns the number of Triangles return this. tri. size(); } 28

Collections as Attributes when using a collection as an attribute of a class X

Collections as Attributes when using a collection as an attribute of a class X you need to decide on ownership issues 29 does X own or share its collection? if X owns the collection, does X own the objects held in the collection?

X Shares its Collection with other Xs if X shares its collection with other

X Shares its Collection with other Xs if X shares its collection with other X instances, then the copy constructor does not need to create a new collection 30 the copy constructor can simply assign its collection [notes 5. 3. 3] refer to this as aliasing

Polygonal. Model Copy Constructor 1 public Polygonal. Model(Polygonal. Model p) { // implements aliasing

Polygonal. Model Copy Constructor 1 public Polygonal. Model(Polygonal. Model p) { // implements aliasing (sharing) with other // Polygonal. Model instances this. set. Triangles( p. get. Triangles() ); } private List<Triangle> get. Triangles() { return this. tri; } private void set. Triangles(List<Triangle> tri) { this. tri = tri; } 31 alias: no new List created

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p 1 200 p 2 500 1000 1100. . . 200 Polygonal. Model object tri 700 Array. List<Triangle> object . . . 500 Polygonal. Model object tri 700. . . 32 1000 Triangle object . . . 1100 Triangle object . . .

Test Your Knowledge Suppose you have a Polygonal. Model p 1 that has 100

Test Your Knowledge Suppose you have a Polygonal. Model p 1 that has 100 Triangles. What does the following code print? 1. Polygonal. Model p 2 = new Polygonal. Model(p 1); p 2. clear(); System. out. println( p 2. size() ); System. out. println( p 1. size() ); 33

X Owns its Collection: Shallow Copy if X owns its collection but not the

X Owns its Collection: Shallow Copy if X owns its collection but not the objects in the collection the copy constructor can perform a shallow copy of the collection a shallow copy of a collection means 34 X creates a new collection the references in the collection are aliases for references in the other collection

X Owns its Collection: Shallow Copy the hard way to perform a shallow copy

X Owns its Collection: Shallow Copy the hard way to perform a shallow copy // assume there is an Array. List<Date> dates Array. List<Date> s. Copy = new Array. List<Date>(); for(Date d : dates) shallow copy: new List { created but elements s. Copy. add(d); are all aliases } add does not create new objects 35

X Owns its Collection: Shallow Copy the easy way to perform a shallow copy

X Owns its Collection: Shallow Copy the easy way to perform a shallow copy // assume there is an Array. List<Date> dates Array. List<Date> s. Copy = new Array. List<Date>(dates); 36

Polygonal. Model Copy Constructor 2 public Polygonal. Model(Polygonal. Model p) { // implements shallow

Polygonal. Model Copy Constructor 2 public Polygonal. Model(Polygonal. Model p) { // implements shallow copying this. tri = new Array. List<Triangle>(p. get. Triangles()); } 37 shallow copy: new List created, but no new Triangle objects created

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p 1 200 p 2 500 Array. List<Triangle> object 1000 1100. . . 800 Array. List<Triangle> object 200 Polygonal. Model object tri 700 1000 . . . 1100. . . 500 Polygonal. Model object tri 800. . . 1000 Triangle object . . . 1100 Triangle object . . . 38

Test Your Knowledge 2. Suppose you have a Polygonal. Model p 1 that has

Test Your Knowledge 2. Suppose you have a Polygonal. Model p 1 that has 100 Triangles. What does the following code print? Polygonal. Model p 2 = new Polygonal. Model(p 1); p 2. clear(); System. out. println( p 2. size() ); System. out. println( p 1. size() ); 39

Test Your Knowledge 3. Suppose you have a Polygonal. Model p 1 that has

Test Your Knowledge 3. Suppose you have a Polygonal. Model p 1 that has 100 Triangles. What does the following code print? Polygonal. Model p 2 = new Polygonal. Model(p 1); Iterator<Triangle> i 1 = p 1. iterator(); Iterator<Triangle> i 2 = p 2. iterator(); System. out. println(i 1. next() == i 2. next()); 40

X Owns its Collection: Deep Copy if X owns its collection and the objects

X Owns its Collection: Deep Copy if X owns its collection and the objects in the collection the copy constructor must perform a deep copy of the collection a deep copy of a collection means 41 X creates a new collection the references in the collection are references to new objects (that are copies of the objects in other collection)

X Owns its Collection: Deep Copy how to perform a deep copy // assume

X Owns its Collection: Deep Copy how to perform a deep copy // assume there is an Array. List<Date> dates Array. List<Date> d. Copy = new Array. List<Date>(); for(Date d : dates) deep copy: new List { created and new d. Copy. add(new Date(d. get. Time()); elements created } constructor invocation creates a new object 42

Polygonal. Model Copy Constructor 3 public Polygonal. Model(Polygonal. Model p) { // implements deep

Polygonal. Model Copy Constructor 3 public Polygonal. Model(Polygonal. Model p) { // implements deep copying this. tri = new Array. List<Triangle>(); for (Triangle t : p. get. Triangles()) { this. tri. add(new Triangle(t)); } } 43 deep copy: new List created, and new Triangle objects created

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p

Polygonal. Model p 2 = new Polygonal. Model(p 1); 700 100 client invocation p 1 200 p 2 500 Array. List<Triangle> object 1000 1100. . . 800 Array. List<Triangle> object 200 Polygonal. Model object tri 700 2000 . . . 2100. . . 500 Polygonal. Model object tri 800. . . 1000 Triangle object . . . 1100 Triangle object . . . 44 continued on next slide

2000 Triangle object . . . 2100 Triangle object . . . 45

2000 Triangle object . . . 2100 Triangle object . . . 45

Test Your Knowledge 4. Suppose you have a Polygonal. Model p 1 that has

Test Your Knowledge 4. Suppose you have a Polygonal. Model p 1 that has 100 Triangles. What does the following code print? Polygonal. Model p 2 = new Polygonal. Model(p 1); p 2. clear(); System. out. println( p 2. size() ); System. out. println( p 1. size() ); 46

Test Your Knowledge 5. Suppose you have a Polygonal. Model p 1 that has

Test Your Knowledge 5. Suppose you have a Polygonal. Model p 1 that has 100 Triangles. What does the following code print? Polygonal. Model p 2 = new Polygonal. Model(p 1); Iterator<Triangle> i 1 = p 1. iterator(); Iterator<Triangle> i 2 = p 2. iterator(); System. out. println(i 1. next() == i 2. next()); System. out. println(i 1. next(). equals(i 2. next())); 47