23 patterns in 80 minutes: a whirlwind java- centric tour ...charlie/courses/15-214/2016... ·...
TRANSCRIPT
115-214
SchoolofComputerScience
23Patternsin80Minutes:aWhirlwindJava-centricTouroftheGang-of-FourDesignPatterns
JoshBloch CharlieGarrod
215-214
Administrivia
• Homework6checkpointdueFriday5:00pm• FinalexamFriday,Dec16th 5:30–8:30pm,GHC4401– ReviewsessionWednesday,Dec14th 7–9:30pm,DH1112
315-214
Outline
I. CreationalPatternsII. StructuralPatternsIII. BehavioralPatterns
415-214
PatternName
• Intent – theaimofthispattern• Usecase– amotivatingexample• Keytypes – thetypesthatdefinepattern– Italictypenameindicatesabstractclass;typicallythisisaninterfacewhenthepatternisusedinJava
• JDK – example(s)ofthispatternintheJDK
515-214
Illustration
• Codesample,diagram,ordrawing– Timeconstraintsmakeitimpossibletoincludeillustrationsfromsomepatterns
615-214
I.CreationalPatterns
1. Abstractfactory2. Builder3. Factorymethod4. Prototype5. Singleton
715-214
1.AbstractFactory
• Intent– allowcreationoffamiliesofrelatedobjectsindependentofimplementation
• Usecase– look-and-feelinaGUItoolkit– EachL&Fhasitsownwindows,scrollbars,etc.
• Keytypes– Factory withmethodstocreateeachfamilymember,Products
• JDK– notcommon
815-214
AbstractFactoryIllustration
Client
Window
PMWindow MotifWindow
PMScrollBar MotifScrollBar
ScrollBar
WidgetFactoryCreateWindow()CreateScrollBar()
MotifWidgetFactoryCreateWindow()CreateScrollBar()
PMWidgetFactoryCreateWindow()CreateScrollBar()
915-214
2.Builder
• Intent– separateconstructionofcomplexobjectfromrepresentationso samecreationprocesscancreatedifferentrepresentations
• usecase– convertingrichtexttovariousformats• types– Builder,ConcreteBuilders,Director,Products• JDK– StringBuilder,StringBuffer*– Butthereisno(visible)abstractsupertype…– Andbothgeneratesameproductclass(String)
1015-214
Gof4BuilderIllustrationRTFReaderParseRTF()
while(t=nextToken){switchtType{CHAR:builder->AddChar(t.Char)FONT:builder->SetFont(t.Font)PARA:builder->AddParagraph()
}}
TextConverterAddChar(char)SetFont(font)AddParagraph()
ASCIIConverterAddChar(char)GetASCIIText()
TeXConverter
AddChar(char)SetFont(font)AddParagraph()GetTeXText()
GUITextConverter
AddChar(char)SetFont(font)AddParagraph()GetGUIText()
Builders
GUITextTeXTextASCIIText
1115-214
MytakeonBuilder[EJItem1]
• Emulatesnamedparametersinlanguagesthatdon’tsupportthem
• Emulates2n constructorsorfactorieswithnbuildermethods,byallowingthemtobecombinedfreely
• Costisanintermediate(Builder)object
1215-214
EJ-styleBuilderIllustrationNutritionFacts twoLiterDietCoke = new NutritionFacts.Builder(
"Diet Coke", 240, 8).sodium(1).build();
public class NutritionFacts {public static class Builder {
public Builder(String name, int servingSize, int servingsPerContainer) { ... }
public Builder totalFat(int val) { totalFat = val; }public Builder saturatedFat(int val) { satFat = val; }public Builder transFat(int val) { transFat = val; }public Builder cholesterol(int val) { cholesterol = val; }... // 15 more setters
public NutritionFacts build() {return new NutritionFacts(this);
}}private NutritionFacts(Builder builder) { ... }
}
1315-214
3.FactoryMethod
• Intent– abstractcreationalmethodthatletssubclassesdecidewhichclasstoinstantiate
• Usecase– creatingdocumentsinaframework• Keytypes– Creator,whichcontainsabstractmethodtocreateaninstance
• JDK– Iterable.iterator()• RelatedStaticFactorypatternisverycommon– TechnicallynotaGoF pattern,butcloseenough
1415-214
FactoryMethodIllustrationpublic interface Iterable<E> {
public abstract Iterator<E> iterator();}
public class ArrayList<E> implements List<E> {public Iterator<E> iterator() { ... }...
}
public class HashSet<E> implements Set<E> {public Iterator<E> iterator() { ... }...
}
Collection<String> c = ...;
for (String s : c) // Creates an Iterator appropriate to cSystem.out.println(s);
1515-214
4.Prototype
• Intent– createanobjectbycloninganotherandtweakingasnecessary
• Usecase– writingamusicscoreeditorinagraphicaleditorframework
• Keytypes– Prototype• JDK– Cloneable,butavoid(exceptonarrays)– JavaandPrototypepatternareapoorfit
1615-214
5.Singleton
• Intent– ensuringaclasshasonlyoneinstance• Usecase– GoF sayprintqueue,filesystem,companyinanaccountingsystem– Compellingusesarerarebuttheydoexist
• Keytypes– Singleton• JDK– java.lang.Runtime
1715-214
SingletonIllustrationpublic enum Elvis {
ELVIS;
sing(Song song) { ... }
playGuitar(Riff riff) { ... }
eat(Food food) { ... }
take(Drug drug) { ... }}
// Alternative implementationpublic class Elvis {
public static final Elvis ELVIS = new Elvis();private Elvis() { }...
}
1815-214
MytakeonSingleton
• It’saninstance-controlledclass;othersinclude– Staticutilityclass– non-instantiable– Enum – oneinstancepervalue,allvaluesknownatcompiletime
– Internedclass– onecanonicalinstancepervalue,newvaluescreatedatruntime
• Thereisadualitybetweensingletonandstaticutilityclass
1915-214
II.StructuralPatterns
1. Adapter2. Bridge3. Composite4. Decorator5. Façade6. Flyweight7. Proxy
2015-214
1.Adapter
• Intent– convertinterfaceofaclassintoonethatanotherclassrequires,allowinginteroperability
• Usecase– numerous,e.g.,arraysvs.collections• Keytypes– Target,Adaptee,Adapter• JDK– Arrays.asList(T[])
2115-214
AdapterIllustration
Havethisandthis?Usethis!
2215-214
2.Bridge
• Intent– decoupleanabstractionfromitsimplementationsotheycanvaryindependently
• Usecase– portablewindowingtoolkit• Keytypes– Abstraction,Implementor• JDK– JDBC,JavaCryptographyExtension(JCE),JavaNaming&DirectoryInterface(JNDI)
• Bridgepatternvery similartoServiceProvider– Abstraction~API,Implementer ~SPI
2315-214
BridgeIllustration
2415-214
3.Composite
• Intent– composeobjectsintotreestructures.Letclientstreatprimitives&compositionsuniformly.
• Usecase– GUItoolkit(widgetsandcontainers)• Keytype– Componentthatrepresentsbothprimitivesandtheircontainers
• JDK– javax.swing.JComponent
2515-214
CompositeIllustrationpublic interface Expression {
double eval(); // Returns valueString toString(); // Returns infix expression string
}
public class UnaryOperationExpression implements Expression {public UnaryOperationExpression(
UnaryOperator operator, Expression operand);}public class BinaryOperationExpression implements Expression {
public BinaryOperationExpression(BinaryOperator operator,Expression operand1, Expression operand2);
}public class NumberExpression implements Expression {
public NumberExpression(double number);}
2615-214
4.Decorator
• Intent– attachfeaturestoanobjectdynamically• Usecase– attachingbordersinaGUItoolkit• Keytypes– Component,implementbydecoratorand decorated
• JDK– Collections(e.g.,Synchronizedwrappers),java.io streams,Swingcomponents
2715-214
DecoratorIllustration
2815-214
5.Façade
• Intent– provideasimpleunifiedinterfacetoasetofinterfacesinasubsystem– GoF allowforvariantswherethecomplexunderpinningsareexposedandhidden
• Usecase– anycomplexsystem;GoF usecompiler• Keytypes– Façade(thesimpleunifiedinterface)• JDK– java.util.concurrent.Executors
2915-214
FaçadeIllustration
Façade
√√
√
√
√
√ √
Subsystem classes
3015-214
6.Flyweight
• Intent– usesharingtosupportlargenumbersoffine-grainedobjectsefficiently
• Usecase– charactersinadocument• Keytypes– Flyweight(instance-controlled!)– Somestatecanbeextrinsic toreducenumberofinstances
• JDK– Common!Allenums,manyothers– j.u.c.TimeUnit hasnumberofunitsasextrinsicstate
3115-214
FlyweightIllustration
3215-214
7.Proxy
• Intent– surrogateforanotherobject• Usecase– delayloadingofimagestillneeded• Keytypes– Subject,Proxy,RealSubject• Gof mentionseveralflavors– virtualproxy– stand-inthatinstantiateslazily– remoteproxy– localrepresentativeforremoteobj– protectionproxy– deniessomeopstosomeusers– smartreference– doeslockingorref.counting,e.g.
• JDK– RMI,collectionswrappers
3315-214
ProxyIllustrationsVirtual Proxy
Smart Reference Remote Proxy
SynchronizedList ArrayList
aTextDocumentimage anImage
data
in memory on disk
anImageProxyfileName
Client
Proxy
Server
3415-214
III.BehavioralPatterns
1. ChainofResponsibility2. Command3. Interpreter4. Iterator5. Mediator6. Memento7. Observer8. State9. Strategy10. Templatemethod11. Visitor
3515-214
1.ChainofResponsibility
• Intent– avoidcouplingsendertoreceiverbypassingrequestalonguntilsomeonehandlesit
• Usecase– context-sensitivehelpfacility• Keytypes– RequestHandler• JDK– ClassLoader,Properties• ExceptionhandlingcouldbeconsideredaformofChainofResponsibilitypattern
3615-214
2.Command
• Intent– encapsulatearequestasasanobject,lettingyouparameterizeoneactionwithanother,queueorlogrequests,etc.
• Usecase– menutree• Keytype– Command (Runnable)• JDK– Common!Executorframework,etc.• IsitCommandpatternifyourunitrepeatedly?Ifittakesanargument?Returnsaval?
3715-214
CommandIllustrationpublic static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Demo().setVisible(true)); }
3815-214
3.Interpreter
• Intent– givenalanguage,defineclasshierarchyforparsetree,recursivemethodtointerpretit
• Usecase– regularexpressionmatching• Keytypes– Expression,NonterminalExpression,TerminalExpression
• JDK– nousesI’mawareof– Ourexpressionevaluator(HW2)isaclassicexample
• NecessarilyusesCompositepattern!
3915-214
InterpreterIllustrationpublic interface Expression {
double eval(); // Returns valueString toString(); // Returns infix expression string
}
public class UnaryOperationExpression implements Expression {public UnaryOperationExpression(
UnaryOperator operator, Expression operand);}public class BinaryOperationExpression implements Expression {
public BinaryOperationExpression(BinaryOperator operator,Expression operand1, Expression operand2);
}public class NumberExpression implements Expression {
public NumberExpression(double number);}
4015-214
4.Iterator
• Intent– provideawaytoaccesselementsofacollectionwithoutexposingrepresentation
• Usecase– collections• Keytypes– Iterable,Iterator– ButGoF discussinternaliteration,too
• JDK– collections,for-eachstatement,etc.
4115-214
IteratorIllustrationpublic interface Iterable<E> {
public abstract Iterator<E> iterator();}
public class ArrayList<E> implements List<E> {public Iterator<E> iterator() { ... }...
}
public class HashSet<E> implements Set<E> {public Iterator<E> iterator() { ... }...
}
Collection<String> c = ...;
for (String s : c) // Creates an Iterator appropriate to cSystem.out.println(s);
4215-214
5.Mediator
• Intent– defineanobjectthatencapsulateshowasetofobjectsinteract,toreducecoupling.– 𝓞(n)couplingsinsteadof𝓞(n2)
• Usecase– dialogboxwherechangeinonecomponentaffectsbehaviorofothers
• Keytypes– Mediator,Components• JDK– Unclear
4315-214
MediatorIllustration
4415-214
6.Memento
• Intent– withoutviolatingencapsulation,allowclienttocaptureanobject’sstate,andrestore
• Usecase– undostackforoperationsthataren’teasilyundone,e.g.,line-arteditor
• Keytype– Memento(opaquestateobject)• JDK– nonethatI’mawareof(not serialization)
4515-214
7.Observer
• Intent– letobjectsobservethebehaviorofotherobjectssotheycanstayinsync
• Usecase– multipleviewsofadataobjectinaGUI• Keytypes– Subject (“Observable”),Observer– GoF areagnosticonmanydetails!
• JDK– Swing,leftandright
4615-214
ObserverIllustration// Implement roll button and dice type fieldJTextField diceSpecField = new JTextField(diceSpec, 5); // Field widthJButton rollButton = new JButton("Roll");rollButton.addActionListener(event -> {if (!diceSpecField.getText().equals(diceSpec)) {
diceSpec = diceSpecField.getText();dice = Die.dice(diceSpec);jDice.resetDice(dice);
}for (Die d : dice) d.roll();jDice.repaint();
});
4715-214
8.State
• Intent– allowanobjecttoalteritsbehaviorwheninternalstatechanges.“Objectwillappeartochangeclass.”
• Usecase– TCPConnection(whichisstateful)• Keytype– State(Objectdelegatestostate!)• JDK– nonethatI’mawareof,but…–Worksgreat inJava– Useenums asstates– UseAtomicReference<State> tostoreit
4815-214
9.Strategy
• Intent– representabehaviorthatparameterizesanalgorithmforbehaviororperformance
• Usecase– line-breakingfortextcompositing• Keytypes– Strategy• JDK– Comparator
4915-214
StrategyIllustrationComparator isastrategyfororderingpublic static synchronized void main(String[] args) {
Arrays.sort(args, Comparator.reverseOrder());System.out.println(Arrays.toString(args));
Arrays.sort(args, Comparator.comparingInt(String::length));System.out.println(Arrays.toString(args));
}
java Foo i eat wondrous spam[wondrous, spam, i, eat][i, eat, spam, wondrous]
5015-214
10.TemplateMethod
• Intent– defineskeletonofanalgorithmordatastructure,deferringsomedecisionstosubclasses
• Usecase– applicationframeworkthatletspluginsimplementalloperationsondocuments
• Keytypes– AbstractClass,ConcreteClass• JDK– skeletalcollectionimpls (e.g.,AbstractList)
5115-214
TemplateMethodIllustration// List adapter for primitive int arrayspublic static List<Integer> intArrayList(final int[] a) {
return new AbstractList<Integer>() {public Integer get(int i) {
return a[i];}
public Integer set(int i, Integer val) {Integer oldVal = a[i];a[i] = val;return oldVal;
}
public int size() {return a.length;
}};
}
5215-214
11.Visitor
• Intent– representanoperationtobeperformedonelementsofanobjectstructure(e.g.,aparsetree).Visitorletsyoudefineanewoperationwithoutmodifyingthetypehierarchy.
• Usecase– type-checking,pretty-printing,etc.• Keytypes– Visitor,ConcreteVisitors,alltheelementtypesthatgetvisited
• JDK– nonethatI’mawareof
5315-214
VisitorIllustration(1/3)public interface Expression {
public <T> T accept(Visitor<T> v); // No eval or toString! }
public class UnaryOperationExpression implements Expression {public UnaryOperationExpression(
UnaryOperator operator, Expression operand);public <T> T accept(Visitor<T> v) { return v.visitUnaryExpr(this); }
}public class BinaryOperationExpression implements Expression {
public BinaryOperationExpression(BinaryOperator operator,Expression operand1, Expression operand2);
public <T> T accept(Visitor<T> v) { return v.visitBinaryExpr(this) ; }}public class NumberExpression implements Expression {
public NumberExpression(double number);public <T> T accept(Visitor<T> v) { return v.visitNumberExpr(this); }
}
5415-214
VisitorIllustration(2/3)public interface Visitor<T> { // T is result type
public T visitUnaryExpr(UnaryExpression ue);public T visitBinaryExpr(BinaryExpression be);public T visitNumberExpr(NumberExpression ne);
}
public class EvalVisitor implements Visitor<Double> {public Double visitUnaryExpr(UnaryExpression ue) {
return ue.operator.apply(ue.operand.accept(this));}public Double visitBinaryExpr(BinaryExpression be) {
return be.operator.apply(be.operand1.accept(this),be.operand2.accept(this));
}public Double visitNumberExpr(NumberExpression ne) { return ne.number; }
}
5515-214
VisitorIllustration(3/3)public class ToStringVisitor implements Visitor<String> {
public String visitUnaryExpr(UnaryExpression ue) {return ue.operator + ue.operand.accept(this);
}public String visitBinaryExpr(BinaryExpression be) {
return String.format("(%s %s %s)", be.operand1.accept(this),be.operator, be.operand2.accept(this));
}public String visitNumberExpr(NumberExpression ne) {
return Double.toString(ne.number);}
}
// Sample use of visitorsSystem.out.println(e.accept(new ToStringVisitor()) + " = " +
e.accept(new EvalVisitor()));
5615-214
MoreonVisitor
• VisitorisNOTmerelytraversingagraphstructureandapplyingamethod– That’sIterator!
• Theessenceofvisitorisdouble-dispatch– FirstdynamicallydispatchontheVisitor– Thenontheelementbeingvisited
5715-214
Summary
• Nowyouknowall theGangofFourpatterns• Definitionscanbevague• Coverageisincomplete• Butthey’reextremelyvaluable– Theygaveusavocabulary– Andawayofthinkingaboutsoftware
• Lookforpatternsasyoureadandwritesoftware– GoF,non-GoF,andundiscovered