Design Patterns Reconsidered
Upcoming SlideShare
Loading in...5
×
 

Design Patterns Reconsidered

on

  • 4,361 views

Revisiting some popular design patterns in Java: singleton, template method, visitor.

Revisiting some popular design patterns in Java: singleton, template method, visitor.

Statistics

Views

Total Views
4,361
Views on SlideShare
4,260
Embed Views
101

Actions

Likes
17
Downloads
444
Comments
1

5 Embeds 101

http://tech.puredanger.com 76
http://www.slideshare.net 11
http://www.linkedin.com 11
https://www.linkedin.com 2
http://us1.pazou.net 1

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • I especially like the Visitor Types where you suggest names for usual types of visitors, kinda stereotypes for visitors. I think I'll refer to this slide next time I use a visitor, telling the visitor type may help describe my intent more accurately. Cheers
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Design Patterns Reconsidered Design Patterns Reconsidered Presentation Transcript

  • Design Patterns Reconsidered Alex Miller @puredanger
  • What is a Design Pattern? “Each pattern describes a problem which occurs over and over again in our environment and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.” - Christopher Alexander
  • The Patterns Backlash • Copy/paste • Design by template • Cookbook / recipe approach “The Design Patterns solution is to turn the programmer into a fancy macro processor” - M. J. Dominus, “Design Patterns” Aren't View slide
  • The Patterns Backlash • Design patterns aren’t patterns • Just workaround for missing language features “At code level, most design patterns are code smells.” - Stuart Halloway View slide
  • The Patterns Backlash • Overuse “Beginning developers never met a pattern or an object they didn’t like. Encouraging them to experiment with patterns is like throwing gasoline on a fire.” - Jeff Atwood, Coding Horror
  • ...Reconsidered Template Visitor Method Proxy Singleton
  • Singleton
  • There can be only one... Singleton - INSTANCE + getInstance() : Singleton - Singleton() + foo() : Object
  • Classic Singleton
  • Classic Singleton public final class Singleton {
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE =
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton();
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {}
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() {
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE;
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; }
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; } public Object read() {
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; } public Object read() { // nasty database call
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; } public Object read() { // nasty database call }
  • Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; } public Object read() { // nasty database call } }
  • Things go horribly wrong public class Victim { public void something() { Object foo = Singleton.instance().read(); // etc... } }
  • Things go horribly wrong public class Victim { public void something() { Object foo = Singleton.instance().read(); // etc... } } public class TestVictim { public void testSomething() { // Holy crap, how do I // mock the db call in Singleton? } }
  • Create Hidden Singletons Coupling!
  • Interfaces to the rescue public interface Singleton { Object read(); } public class SingletonImpl implements Singleton { public Object read() { // nasty database call return null; } }
  • Dependency injection, you’re my hero! public class Victim { private final Singleton singleton; public Victim(Singleton singleton) { this.singleton = singleton; } public void something() { Object foo = singleton.read(); // etc... } }
  • Now we can test public class TestVictim { public void testSomething() { Singleton s = new MockSingleton(); Victim victim = new Victim(s); victim.something(); // assertions } }
  • Push construction up public class Component { private final Victim victim; public Component() { victim = new Victim( new SingletonImpl() ); } }
  • Up Bubble Singletons
  • Singleton
  • What have we learned? • Interfaces and dependency injection • Reduce hidden coupling • Allow testability • Allow subclassing • Make construction and use flexible • If need only one, control by configuration • Guice • Spring
  • ...Reconsidered Template Visitor Method Proxy Singleton
  • Template Method
  • Template Method public void algorithm() { TemplateAlgorithm step1(); + algorithm() step2(); # step1() step3(); # step2() } # step3() ConcreteAlgorithm1 ConcreteAlgorithm2 # step1() # step2() # step2() # step3()
  • Spring MVC Controllers Controller (interface) AbstractController AbstractUrlViewController UrlFilenameViewController BaseCommandController AbstractCommandController AbstractFormController AbstractWizardFormController SimpleFormController CancellableFormController MultiActionController ParameterizableViewController
  • “What we’ve got here is a failure to communicate....”
  • Refactoring to steps Step1Strategy + step1() TemplateAlgorithm - Step1Strategy Step2Strategy - Step2Strategy + step2() - Step3Strategy + algorithm() Step3Strategy + step3() public void algorithm() { step1Strategy.step1(); step2Strategy.step2(); step3Strategy.step3(); }
  • Sharing context Step1Strategy + step1(Context ctx) TemplateAlgorithm - Step1Strategy Step2Strategy - Step2Strategy + step2(Context ctx) - Step3Strategy + algorithm() Step3Strategy + step3(Context ctx) public void algorithm() { Context Context context = new Context(); step1Strategy.step1(context); step2Strategy.step2(context); step3Strategy.step3(context); }
  • What have we learned? • Prefer composition to inheritance • Allows greater reuse • Communicates intent better • Easier to understand and maintain • More robust as it evolves • Inheritance is a very strong form of coupling • Especially in a single-inheritance language
  • ...Reconsidered Template Visitor Method Proxy Singleton
  • Composite hierarchy Node operation1() operation2() ConcreteNode1 CompositeNode operation1() operation1() operation2() operation2()
  • Visitor Pattern Node accept(NodeVisitor v) ConcreteNode1 CompositeNode accept(NodeVisitor v) accept(NodeVisitor v) NodeVisitor visit(ConcreteNode1 n) visit(ConcreteNode2 n) ... ConcreteVisitor1 ConcreteVisitor2 visit(ConcreteNode1 n) visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(ConcreteNode2 n) ... ...
  • N av iga tio n
  • Internal Navigation public class CompositeNode implements Visitable { private List<Node> nodes; public void accept(NodeVisitor v) { v.visit(this); for(Node n : nodes) { v.visit(n); } } }
  • Navigation oracle public class CompositeNode { private List<Node> nodes; public void accept(NodeVisitor v) { v.visit(this); List<Node> children = Navigation.getChildren(this); for(Node n : children) { n.acceptVisitor(this); } } }
  • Navigation Visitor NodeVisitor visit(ConcreteNode1 n) visit(ConcreteNode2 n) ... ConcreteVisitor1 ConcreteVisitor2 visit(ConcreteNode1 n) visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(ConcreteNode2 n) ... ... NavigationVisitor NavigationVisitor(NodeVisitor v) visit(ConcreteNode1 n) visit(ConcreteNode2 n) ...
  • Evo lutio n
  • Node accept(NodeVisitor v) ConcreteNode1 CompositeNode accept(NodeVisitor v) accept(NodeVisitor v) NewNode accept(NodeVisitor v) NodeVisitor visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(NewNode n) ... ConcreteVisitor1 ConcreteVisitor2 visit(ConcreteNode1 n) visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(ConcreteNode2 n) visit(NewNode n) visit(NewNode n) ... ...
  • NodeVisitor visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(NewNode n) ... BaseVisitor visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(NewNode n) ... ConcreteVisitor1 ConcreteVisitor2 visit(ConcreteNode1 n) visit(ConcreteNode1 n) visit(ConcreteNode2 n) visit(ConcreteNode2 n) visit(NewNode n) visit(NewNode n) ... ...
  • Visitor Types • “Collector” visitor - accumulate state • “Finder” visitor - search and return • “Event” visitor - stateless, fire events • “Transform” visitor - modify while walking • “Validation” visitor - validate and report
  • Visitor abort public class FindVisitor implements ConcreteVisitor { private final int seek; private Node match; public FindVisitor(int seek) { this.seek = seek; } public Node getMatch() { return this.match; } public void visit(ConcreteNode1 n) { if( this.match == null && n.getValue() == seek) { this.match = n;
  • Exceptions public class ComputeVisitor implements ConcreteVisitor { public void visit(ConcreteNode1 n) { try { // blah blah } catch(BadException e) { // what now? } } }
  • What have we learned? • Expression problem is tough • Abstract base classes help plan for evolution • Generics add precision and flexibility by revealing hidden coupling
  • Questions? http://tech.puredanger.com/ presentations/design- patterns-reconsidered