Principles of Software Construction: Objects, Design, and Concurrency...
Transcript of Principles of Software Construction: Objects, Design, and Concurrency...
1 17-214
PrinciplesofSoftwareConstruction: Objects,Design,andConcurrencyPart2:DesigncasestudiesDesigncasestudy:JavaCollectionsCharlieGarrodChrisTimperley
2 17-214
Administrivia
• Homework4bduenextThursday,October17th• Homework4afeedbackavailable
– Canregainupto75%oflostHomework4acredit• DirectlyaddressTAcommentswhenyouturninHomework4c• Turninreviseddesigndocuments+scansofourfeedback+descriptionofwhatyouchanged
https://commons.wikimedia.org/wiki/File:1_carcassonne_aerial_2016.jpg
3 17-214
KeyconceptsfromTuesday
4 17-214
KeyconceptsfromTuesday
• GUIsarefilledwithdesignpatterns– Strategy– Templatemethod– Observer– Composite– Decorator– Adapter– Façade– Command– Chainofresponsibility
5 17-214
Today:JavaCollections
Source: http://wiki3.cosc.canterbury.ac.nz/index.php/User:Jenny_Harlow/Design_study/Java_Collections_Framework
6 17-214
Learninggoalsfortoday
• Understandthedesignchallengesofcollectionlibraries.• Recognizethedesignpatternsusedandhowthosedesign
patternsachievedesigngoals.– Markerinterface– Decorator– Factorymethod– Iterator– Strategy– Templatemethod– Adapter
7 17-214
Designingadatastructurelibrary
• Differentdatatypes:lists,sets,maps,stacks,queues,…• Differentrepresentations
– Array-basedlistsvs.linkedlists– Hash-basedsetsvs.tree-basedsets– …
• Manyalternativedesigndecisions– Mutablevs.immutable– Sortedvs.unsorted– Primitivedatavs.objects– Acceptsnullornot– Acceptsduplicatesornot– Concurrency/thread-safeornot– …
8 17-214
ThephilosophyoftheCollectionsframework
• Powerfulandgeneral• Smallinsizeandconceptualweight
– Mustfeelfamiliar– Onlyincludefundamentaloperations– "Funandeasytolearnanduse"
9 17-214
OverviewoftheCollectionsframework
• Coreinterfaces• General-purposeimplementations• Wrapperandspecial-purposeimplementations• Abstractimplementationsforeasyreuse• Separatealgorithmslibrary
10 17-214
Example:Howtofindanagrams
• Alphabetizethecharactersineachword– cat→act,dog→dgo,mouse→emosu– Resultingstringiscalledalphagram
• Anagramssharethesamealphagram!– stop→opst,post→opst,tops→opst,opts→opst
• Sogothroughwordlistmaking“multimap”fromalphagramtoword!
11 17-214
HowtofindanagramsinJava(1)
publicstaticvoidmain(String[]args)throwsIOException{//ReadwordsfromfileandputintoasimulatedmultimapMap<String,List<String>>groups=newHashMap<>();try(Scanners=newScanner(newFile(args[0]))){while(s.hasNext()){Stringword=s.next();Stringalpha=alphabetize(word);List<String>group=groups.get(alpha);if(group==null)groups.put(alpha,group=newArrayList<>());group.add(word);}}
12 17-214
HowtofindanagramsinJava(2)
//PrintallanagramgroupsabovesizethresholdintminGroupSize=Integer.parseInt(args[1]);for(List<String>group:groups.values())if(group.size()>=minGroupSize)System.out.println(group.size()+":"+group);}//ReturnsthealphagramforastringprivatestaticStringalphabetize(Strings){char[]a=s.toCharArray();Arrays.sort(a);returnnewString(a);}
13 17-214
TwoslidesinJavavs.achapterinSTLJava’sverbosityissomewhatexaggerated
14 17-214
TheCollectioninterface
publicinterfaceCollection<E>{intsize();booleanisEmpty();booleancontains(Objectelement);booleanadd(Eelement);//Optionalbooleanremove(Objectelement);//OptionalIterator<E>iterator();Object[]toArray();T[]toArray(Ta[]);//BulkoperationsbooleancontainsAll(Collection<?>c);booleanaddAll(Collection<?extendsE>c);//OptionalbooleanremoveAll(Collection<?>c);//OptionalbooleanretainAll(Collection<?>c);//Optionalvoidclear();//Optional…}
14
15 17-214
TheListinterface:anorderedcollection
publicinterfaceList<E>extendsCollection<E>{Eget(intindex);Eset(intindex,Eelement);//Optionalvoidadd(intindex,Eelement);//OptionalObjectremove(intindex);//OptionalbooleanaddAll(intindex,Collection<?extendsE>c);//OptionalintindexOf(Objecto);intlastIndexOf(Objecto);List<E>subList(intfrom,intto);ListIterator<E>listIterator();ListIterator<E>listIterator(intindex);}
16 17-214
TheSetinterface:collectionofdistinctitems
• Addsnomethods!• Specificationrequiresnoduplicateitemsincollection• Themarkerinterfacedesignpattern
– Markerinterfacesaddinvariants,nocode
publicinterfaceSet<E>extendsCollection<E>{}
17 17-214
TheMapinterface:key-valuemapping
publicinterfaceMap<K,V>{intsize();booleanisEmpty();booleancontainsKey(Objectkey);booleancontainsValue(Objectvalue);Objectget(Objectkey);Objectput(Kkey,Vvalue);//OptionalObjectremove(Objectkey);//OptionalvoidputAll(Map<?extendsK,?extendsV>t);//Opt.voidclear();//Optional//CollectionviewspublicSet<K>keySet();publicCollection<V>values();publicSet<Map.Entry<K,V>>entrySet();}
18 17-214
RecalltheIteratorinterface
publicinterfaceIterator<E>{booleanhasNext();Enext();voidremove();//Optional}
19 17-214
Aside:Thefactorymethodpattern
publicinterfaceCollection<E>{intsize();booleanisEmpty();booleancontains(Objectelement);booleanadd(Eelement);//Optionalbooleanremove(Objectelement);//OptionalIterator<E>iterator();Object[]toArray();T[]toArray(Ta[]);//BulkoperationsbooleancontainsAll(Collection<?>c);booleanaddAll(Collection<?extendsE>c);//OptionalbooleanremoveAll(Collection<?>c);//OptionalbooleanretainAll(Collection<?>c);//Optionalvoidclear();//Optional…}
19
Definesaninterfaceforcreatinganiterator,butallowscollectionimplementationtodecidewhichiteratortocreate.
20 17-214
Thefactorymethoddesignpattern
• Problem:Subclassesneedtocontrolthetypeofobjectcreated• Solution:Defineanmethodthatconstructstheobject;
subclassescanoverridethemethod.• Consequences:
– Namescanbemeaningful,self-documenting– Canavoidconstructinganewobject– Mightbehardtodistinguishfactorymethodfromothermethods
21 17-214
Otherfactorymethodexamples
• Fromjava.util.Collections:List<T>emptyList();Set<T>emptySet();Map<K,V>emptyMap();Set<T>singleton(Titem);List<T>singletonList(Titem);List<T>nCopies(intn,Titem);
22 17-214
Interface ImplementationSet HashSetList ArrayListQueue ArrayDequeDeque ArrayDeque[stack] ArrayDequeMap HashMap
General-purposeimplementations
23 17-214
General-purposeimplementations(continued)
Interface Implementation(s)List LinkedListSet LinkedHashSet
TreeSetEnumSet
Queue PriorityQueueMap LinkedHashMap
TreeMapEnumMap
24 17-214
Wrapperandspecial-purposeimplementations
• Unmodifiablecollections(fromjava.util.Collections):Collection<T>unmodifiableCollection(Collection<?extendsT>c);List<T>unmodifiableList(List<?extendsT>list);Map<K,V>unmodifiableMap(Map<?extendsK,?extendsV>m);
25 17-214
Wrapperandspecial-purposeimplementations
• Unmodifiablecollections(fromjava.util.Collections):Collection<T>unmodifiableCollection(Collection<?extendsT>c);List<T>unmodifiableList(List<?extendsT>list);Map<K,V>unmodifiableMap(Map<?extendsK,?extendsV>m);
• Synchronizedcollections(fromjava.util.Collections):Collection<T>synchronizedCollection(Collection<?extendsT>c);List<T>synchronizedList(List<?extendsT>list);Map<K,V>synchronizedMap(Map<?extendsK,?extendsV>m);
26 17-214
Wrapperandspecial-purposeimplementations
• Unmodifiablecollections(fromjava.util.Collections):Collection<T>unmodifiableCollection(Collection<?extendsT>c);List<T>unmodifiableList(List<?extendsT>list);Map<K,V>unmodifiableMap(Map<?extendsK,?extendsV>m);
• Synchronizedcollections(fromjava.util.Collections):Collection<T>synchronizedCollection(Collection<?extendsT>c);List<T>synchronizedList(List<?extendsT>list);Map<K,V>synchronizedMap(Map<?extendsK,?extendsV>m);
• AListbackedfromanarray(fromjava.util.Arrays):List<T>asList(T…a);
Theadapterpattern:ReturnsaspecializedlistimplementationthatadaptsthearrayAPItothejava.util.ListAPI
27 17-214
e.g.,TheUnmodifiableCollectionclass
publicstatic<T>Collection<T>unmodifiableCollection(Collection<T>c){returnnewUnmodifiableCollection<>(c);
}classUnmodifiableCollection<E>
implementsCollection<E>,Serializable{
finalCollection<E>c;
UnmodifiableCollection(Collection<>c){this.c=c;}publicint size() {returnc.size();}publicbooleanisEmpty() {returnc.isEmpty();}publicbooleancontains(Objecto){returnc.contains(o);}publicObject[]toArray() {returnc.toArray();}public<T>T[]toArray(T[]a) {returnc.toArray(a);}publicString toString() {returnc.toString();}publicbooleanadd(Ee){thrownewUnsupportedOperationException();}publicbooleanremove(Objecto) {thrownewUnsupportedOperationException();}publicbooleancontainsAll(Collection<?>coll){returnc.containsAll(coll);}publicbooleanaddAll(Collection<?extendsE>coll){thrownewUnsupportedOperationException();}publicbooleanremoveAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicbooleanretainAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicvoidclear(){thrownewUnsupportedOperationException();}
}
28 17-214
e.g.,TheUnmodifiableCollectionclass
publicstatic<T>Collection<T>unmodifiableCollection(Collection<T>c){returnnewUnmodifiableCollection<>(c);
}classUnmodifiableCollection<E>
implementsCollection<E>,Serializable{
finalCollection<E>c;
UnmodifiableCollection(Collection<>c){this.c=c;}publicint size() {returnc.size();}publicbooleanisEmpty() {returnc.isEmpty();}publicbooleancontains(Objecto){returnc.contains(o);}publicObject[]toArray() {returnc.toArray();}public<T>T[]toArray(T[]a) {returnc.toArray(a);}publicString toString() {returnc.toString();}publicbooleanadd(Ee){thrownewUnsupportedOperationException();}publicbooleanremove(Objecto) {thrownewUnsupportedOperationException();}publicbooleancontainsAll(Collection<?>coll){returnc.containsAll(coll);}publicbooleanaddAll(Collection<?extendsE>coll){thrownewUnsupportedOperationException();}publicbooleanremoveAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicbooleanretainAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicvoidclear(){thrownewUnsupportedOperationException();}
}
What design pattern is this?
29 17-214
e.g.,TheUnmodifiableCollectionclass
publicstatic<T>Collection<T>unmodifiableCollection(Collection<T>c){returnnewUnmodifiableCollection<>(c);
}classUnmodifiableCollection<E>
implementsCollection<E>,Serializable{finalCollection<E>c;
UnmodifiableCollection(Collection<>c){this.c=c;}publicint size() {returnc.size();}publicbooleanisEmpty() {returnc.isEmpty();}publicbooleancontains(Objecto){returnc.contains(o);}publicObject[]toArray() {returnc.toArray();}public<T>T[]toArray(T[]a) {returnc.toArray(a);}publicString toString() {returnc.toString();}publicbooleanadd(Ee){thrownewUnsupportedOperationException();}publicbooleanremove(Objecto) {thrownewUnsupportedOperationException();}publicbooleancontainsAll(Collection<?>coll){returnc.containsAll(coll);}publicbooleanaddAll(Collection<?extendsE>coll){thrownewUnsupportedOperationException();}publicbooleanremoveAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicbooleanretainAll(Collection<?>coll){thrownewUnsupportedOperationException();}publicvoidclear(){thrownewUnsupportedOperationException();}
}
What design pattern is this?
UnmodifiableCollection decorates Collection by removing functionality…
30 17-214
Abstractimplementationsforeasyreuse
publicabstractAbstractList<E>extendsAbstractCollection<E>implementsList<E>{abstractpublicintsize();abstractpublicEget(intindex);publicbooleanisEmpty(){returnsize()==0;}publicbooleancontains(Objectelement){for(inti=0;i<size();i++){if(get(i).equals(element)){returntrue;}}returnfalse;}publicbooleanadd(intindex,Eelement){thrownewUnsupportedOperationException();}publicbooleanremove(intindex){thrownewUnsupportedOperationException();}…}
31 17-214
Implementinganewlisttype
/***Returnsanunmodifiableviewofthegivenlist,equivalentto*thereverseofthegivenlist.Thereturnvalueisbacked*bytheoriginallist,usingO(1)additionalspace.*/publicstatic<T>List<T>reverseOf(List<T>list){...}
32 17-214
Implementinganewlisttype
/***Returnsanunmodifiableviewofthegivenlist,equivalentto*thereverseofthegivenlist.Thereturnvalueisbacked*bytheoriginallist,usingO(1)additionalspace.*/publicstatic<T>List<T>reverseOf(List<T>list){returnnewAbstractList<T>(){
@Overridepublicintsize(){returnlist.size();}@OverridepublicTget(intindex){returnlist.get(size()–index–1)}};}
33 17-214
Abstractimplementationsforeasyreuse
publicabstractAbstractList<E>extendsAbstractCollection<E>implementsList<E>{abstractpublicintsize();abstractpublicEget(intindex);publicbooleanisEmpty(){returnsize()==0;}publicbooleancontains(Objectelement){…}publicbooleanadd(intindex,Eelement){thrownewUnsupportedOperationException();}publicbooleanremove(intindex){thrownewUnsupportedOperationException();}…}
What design pattern is this?
34 17-214
Abstractimplementationsforeasyreuse
publicabstractAbstractList<E>extendsAbstractCollection<E>implementsList<E>{abstractpublicintsize();abstractpublicEget(intindex);publicbooleanisEmpty(){returnsize()==0;}publicbooleancontains(Objectelement){…}publicbooleanadd(intindex,Eelement){thrownewUnsupportedOperationException();}publicbooleanremove(intindex){thrownewUnsupportedOperationException();}…}
What design pattern is this?
The template method design pattern: size and get are primitive operations, other methods are template methods.
35 17-214
35
Reusablealgorithmsinjava.util.Collections
static<TextendsComparable<?superT>>voidsort(List<T>list);
staticintbinarySearch(Listlist,Objectkey);
static<TextendsComparable<?superT>>Tmin(Collection<T>coll);
static<TextendsComparable<?superT>>Tmax(Collection<T>coll);
static<E>voidfill(List<E>list,Ee);
static<E>voidcopy(List<E>dest,List<?ExtendsE>src);
staticvoidreverse(List<?>list);
staticvoidshuffle(List<?>list);
36 17-214
e.g.sortingaCollection
• UsingCollections.sort:publicstaticvoidmain(String[]args){List<String>list=Arrays.asList(args);Collections.sort(list);for(Strings:list){System.out.println(s);}}
37 17-214
Sortingyourowntypesofobjects
publicinterfaceComparable<T>{intcompareTo(To);}• Generalcontracts:
– a.compareTo(b)shouldreturn:<0 ifaislessthanb
0 ifaandbareequal>0 ifaisgreaterthanb
– Shoulddefineatotalorder:• Ifa.compareTo(b)<0andb.compareTo(c)<0,thena.compareTo(c)shouldbe<0
• Ifa.compareTo(b)<0,thenb.compareTo(a)shouldbe>0– Shouldusuallybeconsistentwith.equals:
• a.compareTo(b)==0iffa.equals(b)
38 17-214
Comparableobjects–anexample
publicclassIntegerimplementsComparable<Integer>{privatefinalintval;publicInteger(intval){this.val=val;}…publicintcompareTo(Integero){if(val<o.val)return-1;if(val==o.val)return0;return1;}}
39 17-214
Comparableobjects–anotherexample
• Make Name comparable: publicclassName{privatefinalStringfirst,last;publicName(Stringfirst,Stringlast){if(first==null||last==null)thrownewNullPointerException();this.first=first;this.last=last;}…
}• Hint:StringsimplementComparable<String>
40 17-214
Comparableobjects–anotherexample
• Make Name comparable: publicclassNameimplementsComparable<Name>{privatefinalStringfirst,last;publicName(Stringfirst,Stringlast){if(first==null||last==null)thrownewNullPointerException();this.first=first;this.last=last;}publicintcompareTo(Nameo){intlastComparison=last.compareTo(o.last);if(lastComparison!=0)returnlastComparison;returnfirst.compareTo(o.first);}
} Hint:StringsimplementComparable<String>
41 17-214
Alternativecomparisons
publicclassEmployeeimplementsComparable<Employee>{protectedNamename;protectedintsalary;…}• WhatifwewanttosortEmployeesbyname,usually,but
sometimessortbysalary?
42 17-214
Alternativecomparisons
publicclassEmployeeimplementsComparable<Employee>{protectedNamename;protectedintsalary;…}• WhatifwewanttosortEmployeesbyname,usually,but
sometimessortbysalary?• Answer:There'saStrategypatterninterfaceforthat:publicinterfaceComparator<T>{publicintcompare(To1,To2);}
43 17-214
WritingaComparatorobjectpublicclassEmployeeimplementsComparable<Employee>{protectedNamename;protectedintsalary;publicintcompareTo(Employeeo){returnname.compareTo(o.name);}}publicclassSalaryComparatorimplementsComparator<Employee>{publicintcompare(Employeeo1,Employeeo2){returno1.salary–o2.salary;}}
44 17-214
Summary
• Collectionsasreusableandextensibledatastructures– designforreuse– designforchange
• Iteratorstoabstractoverinternalstructure• Decoratortoattachbehavioratruntime• Templatemethodsandfactorymethodstosupport
customizationinsubclasses• Adapterstoconvertbetweenimplementations• Strategypatternforsorting