Principles of So3ware Construc9on: Objects, Design, and Concurrency Designing classes Introduc9on to design paDerns, con9nued and Parametric polymorphism (with Java generics) Josh Bloch Charlie Garrod School of Computer Science 15-214 1
Administrivia • Homework 3 due Sunday, September 25 th • Midterm exam next Thursday (September 29 th ) – Review session Wednesday, September 28 th , 7-9 pm, HH B103 15-214 2
Java puzzlers: “ Animal Farm ” (2005) public class AnimalFarm { public static void main(String[] args) { final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println("Animals are equal: " + pig == dog); } } 15-214 From An Evening Of Puzzlers by Josh Bloch 3
What does it print? public class AnimalFarm { public static void main(String[] args) { final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println("Animals are equal: " + pig == dog); } } (a) Animals are equal: true (b) Animals are equal: false (c) It varies (d) None of the above 15-214 4
What does it print? (a) Animals are equal: true (b) Animals are equal: false (c) It varies (d) None of the above: false The + operator binds tighter than == 15-214 5
Another look public class AnimalFarm { public static void main(String[] args) { final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println("Animals are equal: " + pig == dog); } } 15-214 6
You could try to fix it like this... public class AnimalFarm { public static void main(String[] args) { final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println("Animals are equal: " + (pig == dog)); } } Prints Animals are equal: false 15-214 7
But this is much better public class AnimalFarm { public static void main(String[] args) { final String pig = "length: 10"; final String dog = "length: " + pig.length(); System.out.println("Animals are equal: " + pig.equals(dog)); } } Prints Animals are equal: true 15-214 8
The moral • Use parens, not spacing, to express intent • Use parens whenever there is any doubt • Don ’ t depend on interning of string constants • Use .equals , not == for object references 15-214 9
Key concepts from Thursday… 15-214 10
UML you should know • Interfaces vs. classes • Fields vs. methods • Rela9onships: – "extends" (inheritance) – "implements" (realiza9on) – "has a" (aggrega9on) – non-specific associa9on • Visibility: + (public) - (private) # (protected) • Basic best prac9ces… 15-214 11
Discussion with design paDerns • Carpentry: – "Is a dovetail joint or a miter joint beDer here?" • So3ware Engineering: – "Is a strategy paDern or a template method beDer here?" 15-214 12
Strategy paDern • Problem: Clients need different variants of an algorithm • Solu9on: Create an interface for the algorithm, with an implemen9ng class for each variant of the algorithm • Consequences: – Easily extensible for new algorithm implementa9ons – Separates algorithm from client context – Introduces an extra interface and many classes: • Code can be harder to understand • Lots of overhead if the strategies are simple 15-214 13
Avoiding instanceof with the template method pattern public void doSomething(Account acct) { float adj = 0.0; if (acct instanceof CheckingAccount) { checkingAcct = (CheckingAccount) acct; adj = checkingAcct.getFee(); } else if (acct instanceof SavingsAccount) { savingsAcct = (SavingsAccount) acct; adj = savingsAcct.getInterest(); } … } Instead: public void doSomething(Account acct) { long adj = acct.getMonthlyAdjustment(); … } 15-214 14
Today: • A puzzler… • More design paDerns for reuse – Iterator paDern (reprised) – Decorator paDern • Parametric polymorphism (a.k.a. generics) 15-214 15
Traversing a collec9on • Old-school Java for loop for ordered types List<String> arguments = …; for (int i = 0; i < arguments.size(); i++) { System.out.println(arguments.get(i)); } • Modern standard Java for-each loop List<String> arguments = …; for (String s : arguments) { System.out.println(s); Works for every implementa9on } of Iterable : public interface Iterable<E> { public Iterator<E> iterator(); } 15-214 16
The Iterator interface public interface java.util.Iterator<E> { boolean hasNext(); E next(); void remove(); // removes previous returned item } // from the underlying collection • To use explicitly, e.g.: List<String> arguments = …; for (Iterator<String> it = arguments.iterator(); it.hasNext(); ) { String s = it.next(); System.out.println(s); } 15-214 17
Iterator design paDern • Problem: Clients need uniform strategy to access all elements in a container, independent of the container type – Order is unspecified, but access every element once • Solu9on: A strategy paDern for itera9on • Consequences: – Hides internal implementa9on of underlying container – Easy to change container type – Facilitates communica9on between parts of the program 15-214 18
A design principle for reuse: low coupling • Each component should depend on as few other components as possible • Benefits of low coupling: – Enhances understandability – Reduces cost of change – Eases reuse 15-214 19
Gejng an Iterator public interface Collection<E> extends Iterable<E> { boolean add(E e); boolean addAll(Collection<? extends E> c); boolean remove(Object e); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); boolean contains(Object e); boolean containsAll(Collection<?> c); void clear(); int size(); Defines an interface for boolean isEmpty(); creating an Iterator, Iterator<E> iterator(); but allows Collection Object[] toArray() implementation to decide <T> T[] toArray(T[] a); which Iterator to create. … } 15-214 20
An Iterator implementa9on for Pairs public class Pair<E> { private final E first, second; public Pair(E f, E s) { first = f; second = s; } Pair<String> pair = new Pair<String>("foo", "bar"); } for (String s : pair) { … } 15-214 21
An Iterator implementa9on for Pairs public class Pair<E> implements Iterable<E> { private final E first, second; public Pair(E f, E s) { first = f; second = s; } public Iterator<E> iterator() { return new PairIterator(); } private class PairIterator implements Iterator<E> { private boolean seenFirst = false, seenSecond = false; public boolean hasNext() { return !seenSecond; } public E next() { if (!seenFirst) { seenFirst = true; return first; } if (!seenSecond) { seenSecond = true; return second; } throw new NoSuchElementException(); } public void remove() { throw new UnsupportedOperationException(); } Pair<String> pair = new Pair<String>("foo", "bar"); } for (String s : pair) { … } } 15-214 22
Using a java.util.Iterator<E> : A warning • The default Collec9ons implementa9ons are mutable… • …but their Iterator implementa9ons assume the collec9on does not change while the Iterator is being used – You will get a ConcurrentModificationException 15-214 23
Using a java.util.Iterator<E> : A warning • The default Collec9ons implementa9ons are mutable… • …but their Iterator implementa9ons assume the collec9on does not change while the Iterator is being used – You will get a ConcurrentModificationException – If you simply want to remove an item: List<String> arguments = …; for (Iterator<String> it = arguments.iterator(); it.hasNext(); ) { String s = it.next(); if (s.equals("Charlie")) arguments.remove("Charlie"); // runtime error } 15-214 24
Using a java.util.Iterator<E> : A warning • The default Collec9ons implementa9ons are mutable… • …but their Iterator implementa9ons assume the collec9on does not change while the Iterator is being used – You will get a ConcurrentModificationException – If you simply want to remove an item: List<String> arguments = …; for (Iterator<String> it = arguments.iterator(); it.hasNext(); ) { String s = it.next(); if (s.equals("Charlie")) it.remove(); } 15-214 25
Today: • A puzzler… • More design paDerns for reuse – Iterator paDern (reprised) – Decorator paDern • Parametric polymorphism (a.k.a. generics) 15-214 26
Limita9ons of inheritance • Suppose you want various extensions of a Stack data structure… – UndoStack : A stack that lets you undo previous push or pop opera9ons – SecureStack : A stack that requires a password – SynchronizedStack : A stack that serializes concurrent accesses 15-214 27
Recommend
More recommend