SlideShare uma empresa Scribd logo
1 de 55
Baixar para ler offline
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
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
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

Mais conteúdo relacionado

Mais procurados

Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
Pramod Kumar
 

Mais procurados (20)

Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Headless Js Testing
Headless Js TestingHeadless Js Testing
Headless Js Testing
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기#살아있다 #자프링외길12년차 #코프링2개월생존기
#살아있다 #자프링외길12년차 #코프링2개월생존기
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
Solid Software Design Principles
Solid Software Design PrinciplesSolid Software Design Principles
Solid Software Design Principles
 
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
«Objective-C Runtime в примерах» — Алексей Сторожев, e-Legion
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
Advanced JavaScript Concepts
Advanced JavaScript ConceptsAdvanced JavaScript Concepts
Advanced JavaScript Concepts
 
Introduction to Clean Code
Introduction to Clean CodeIntroduction to Clean Code
Introduction to Clean Code
 
Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8Reactive Access to MongoDB from Java 8
Reactive Access to MongoDB from Java 8
 
Magic methods
Magic methodsMagic methods
Magic methods
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Building High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterBuilding High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 Firestarter
 
Dart London hackathon
Dart  London hackathonDart  London hackathon
Dart London hackathon
 

Semelhante a Design Patterns Reconsidered

10 Typical Enterprise Java Problems
10 Typical Enterprise Java Problems10 Typical Enterprise Java Problems
10 Typical Enterprise Java Problems
Eberhard Wolff
 

Semelhante a Design Patterns Reconsidered (20)

2. Design patterns. part #2
2. Design patterns. part #22. Design patterns. part #2
2. Design patterns. part #2
 
RxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камниRxJava и Android. Плюсы, минусы, подводные камни
RxJava и Android. Плюсы, минусы, подводные камни
 
The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196The Ring programming language version 1.7 book - Part 85 of 196
The Ring programming language version 1.7 book - Part 85 of 196
 
Deuce STM - CMP'09
Deuce STM - CMP'09Deuce STM - CMP'09
Deuce STM - CMP'09
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Design pattern - part 3
Design pattern - part 3Design pattern - part 3
Design pattern - part 3
 
Test Engine
Test EngineTest Engine
Test Engine
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
 
Devoxx 2012 (v2)
Devoxx 2012 (v2)Devoxx 2012 (v2)
Devoxx 2012 (v2)
 
Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
 Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at... Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
Processing large-scale graphs with Google(TM) Pregel by MICHAEL HACKSTEIN at...
 
Design patterns with kotlin
Design patterns with kotlinDesign patterns with kotlin
Design patterns with kotlin
 
Test Engine
Test EngineTest Engine
Test Engine
 
10 Typical Enterprise Java Problems
10 Typical Enterprise Java Problems10 Typical Enterprise Java Problems
10 Typical Enterprise Java Problems
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Processing large-scale graphs with Google(TM) Pregel
Processing large-scale graphs with Google(TM) PregelProcessing large-scale graphs with Google(TM) Pregel
Processing large-scale graphs with Google(TM) Pregel
 
Frank Celler – Processing large-scale graphs with Google(TM) Pregel - NoSQL m...
Frank Celler – Processing large-scale graphs with Google(TM) Pregel - NoSQL m...Frank Celler – Processing large-scale graphs with Google(TM) Pregel - NoSQL m...
Frank Celler – Processing large-scale graphs with Google(TM) Pregel - NoSQL m...
 
Session #6 loaders and adapters
Session #6  loaders and adaptersSession #6  loaders and adapters
Session #6 loaders and adapters
 
Object-oriented Basics
Object-oriented BasicsObject-oriented Basics
Object-oriented Basics
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
TDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with AndroidTDD and mobile development: some forgotten techniques, illustrated with Android
TDD and mobile development: some forgotten techniques, illustrated with Android
 

Mais de Alex Miller

Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow Test
Alex Miller
 

Mais de Alex Miller (20)

Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)Clojure/West Overview (12/1/11)
Clojure/West Overview (12/1/11)
 
Concurrent Stream Processing
Concurrent Stream ProcessingConcurrent Stream Processing
Concurrent Stream Processing
 
Stream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/joinStream Execution with Clojure and Fork/join
Stream Execution with Clojure and Fork/join
 
Cracking clojure
Cracking clojureCracking clojure
Cracking clojure
 
Releasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic WebReleasing Relational Data to the Semantic Web
Releasing Relational Data to the Semantic Web
 
Clojure: The Art of Abstraction
Clojure: The Art of AbstractionClojure: The Art of Abstraction
Clojure: The Art of Abstraction
 
Tree Editing with Zippers
Tree Editing with ZippersTree Editing with Zippers
Tree Editing with Zippers
 
Groovy concurrency
Groovy concurrencyGroovy concurrency
Groovy concurrency
 
Blogging ZOMG
Blogging ZOMGBlogging ZOMG
Blogging ZOMG
 
Innovative Software
Innovative SoftwareInnovative Software
Innovative Software
 
Scaling Your Cache
Scaling Your CacheScaling Your Cache
Scaling Your Cache
 
Caching In The Cloud
Caching In The CloudCaching In The Cloud
Caching In The Cloud
 
Scaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At ScaleScaling Your Cache And Caching At Scale
Scaling Your Cache And Caching At Scale
 
Marshmallow Test
Marshmallow TestMarshmallow Test
Marshmallow Test
 
Strange Loop Conference 2009
Strange Loop Conference 2009Strange Loop Conference 2009
Strange Loop Conference 2009
 
Cold Hard Cache
Cold Hard CacheCold Hard Cache
Cold Hard Cache
 
Scaling Hibernate with Terracotta
Scaling Hibernate with TerracottaScaling Hibernate with Terracotta
Scaling Hibernate with Terracotta
 
Project Fortress
Project FortressProject Fortress
Project Fortress
 
Java Collections API
Java Collections APIJava Collections API
Java Collections API
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 

Último

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Último (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 

Design Patterns Reconsidered

  • 1. Design Patterns Reconsidered Alex Miller @puredanger
  • 2. 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
  • 3.
  • 4. 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
  • 5. 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
  • 6. 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
  • 7. ...Reconsidered Template Visitor Method Proxy Singleton
  • 9. There can be only one... Singleton - INSTANCE + getInstance() : Singleton - Singleton() + foo() : Object
  • 11. Classic Singleton public final class Singleton {
  • 12. Classic Singleton public final class Singleton { private static Singleton INSTANCE =
  • 13. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton();
  • 14. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {}
  • 15. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() {
  • 16. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE;
  • 17. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; }
  • 18. Classic Singleton public final class Singleton { private static Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton instance() { return INSTANCE; } public Object read() {
  • 19. 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
  • 20. 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 }
  • 21. 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 } }
  • 22. Things go horribly wrong public class Victim { public void something() { Object foo = Singleton.instance().read(); // etc... } }
  • 23. 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? } }
  • 24. Create Hidden Singletons Coupling!
  • 25. Interfaces to the rescue public interface Singleton { Object read(); } public class SingletonImpl implements Singleton { public Object read() { // nasty database call return null; } }
  • 26. 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... } }
  • 27. Now we can test public class TestVictim { public void testSomething() { Singleton s = new MockSingleton(); Victim victim = new Victim(s); victim.something(); // assertions } }
  • 28. Push construction up public class Component { private final Victim victim; public Component() { victim = new Victim( new SingletonImpl() ); } }
  • 29. Up Bubble Singletons
  • 31. 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
  • 32. ...Reconsidered Template Visitor Method Proxy Singleton
  • 34. Template Method public void algorithm() { TemplateAlgorithm step1(); + algorithm() step2(); # step1() step3(); # step2() } # step3() ConcreteAlgorithm1 ConcreteAlgorithm2 # step1() # step2() # step2() # step3()
  • 35. Spring MVC Controllers Controller (interface) AbstractController AbstractUrlViewController UrlFilenameViewController BaseCommandController AbstractCommandController AbstractFormController AbstractWizardFormController SimpleFormController CancellableFormController MultiActionController ParameterizableViewController
  • 36.
  • 37. “What we’ve got here is a failure to communicate....”
  • 38. Refactoring to steps Step1Strategy + step1() TemplateAlgorithm - Step1Strategy Step2Strategy - Step2Strategy + step2() - Step3Strategy + algorithm() Step3Strategy + step3() public void algorithm() { step1Strategy.step1(); step2Strategy.step2(); step3Strategy.step3(); }
  • 39. 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); }
  • 40. 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
  • 41. ...Reconsidered Template Visitor Method Proxy Singleton
  • 42. Composite hierarchy Node operation1() operation2() ConcreteNode1 CompositeNode operation1() operation1() operation2() operation2()
  • 43. 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) ... ...
  • 44. N av iga tio n
  • 45. 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); } } }
  • 46. 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); } } }
  • 47. 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) ...
  • 48. Evo lutio n
  • 49. 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) ... ...
  • 50. 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) ... ...
  • 51. 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
  • 52. 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;
  • 53. Exceptions public class ComputeVisitor implements ConcreteVisitor { public void visit(ConcreteNode1 n) { try { // blah blah } catch(BadException e) { // what now? } } }
  • 54. What have we learned? • Expression problem is tough • Abstract base classes help plan for evolution • Generics add precision and flexibility by revealing hidden coupling
  • 55. Questions? http://tech.puredanger.com/ presentations/design- patterns-reconsidered