Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Yo Mama’s Got JavaScript Design Patterns!!

Yo Mama’s Got JavaScript Design Patterns!!

Design patterns are core to understanding and reasoning about large code bases.

With JavaScript more and more becoming the major language of awesomeness, it's imperative for devs to be smart about what they write and not leave junky code for future devs to maintain. The original Gang of Four design patterns have been used and applied across many languages, however, not all patterns are equal across languages. JavaScript is unique in that it has many aspects of Functional as well as Object-oriented programming principles. We'll discuss common JS design patterns and practices for large-scale app development, and showcase how you can use them to make life more awesome for all to come.

This is an intro to Design Patterns in JavaScript.

(Presented at Utah Code Camp 2015 held at the University of Utah Spencer Fox Eccles Business Building in SLC, Utah on 03.14.15 9:26:53.5 (pi day, pi time!))

Avatar for Ryan Done

Ryan Done

March 14, 2015

More Decks by Ryan Done

Other Decks in Programming

Transcript

  1. // Audience Note • An understanding of JavaScript will be

    very helpful for this talk, 
 but this is an introduction to design patterns. • There are MANY software design patterns! Today we are
 focusing on the Module, Faҫade and Mediator patterns. • Feel free to jump out if this is not what you expected.
 

  2. // TODO 1. Where did Design Patterns come from? 2.

    Software Patterns emerge 3. JavaScript Patterns for Everyday Awesomeness! 4. Large-scale JS Apps
  3. // TODO 1. Where did Design Patterns come from? 2.

    Software Patterns emerge 3. JavaScript Patterns for Everyday Awesomeness! 4. Large-scale JS Apps
  4. purpose of design patterns 1. Patterns help us communicate 2.

    Patterns save us time 3. Patterns help us abstract ideas and think broader
  5. purpose of design patterns 1. Patterns help us communicate 2.

    Patterns save us time 3. Patterns help us abstract ideas and think broader
  6. –Johnny Appleseed “I want a roof with a top-line that

    follows the full-length of the house. The top-line should be in the center with equal length sides each pitched at the same angle toward the center.”
  7. purpose of design patterns 1. Patterns help us communicate 2.

    Patterns save us time 3. Patterns help us abstract ideas and think broader
  8. purpose of design patterns 1. Patterns help us communicate 2.

    Patterns save us time 3. Patterns help us abstract ideas and think broader
  9. “What if we start with five or six Shed Roofs,

    but we put them on varying planes and warp them a little to make it look more interesting?”
  10. // TODO 1. Where did Design Patterns come from? 2.

    Software Patterns emerge 3. JavaScript Patterns for Everyday Awesomeness! 4. Large-scale JS Apps
  11. –Justin Meyer, author JavaScriptMVC “The secret to building large apps

    is never build large apps. Break your applications into small pieces. Then, assemble those testable, bite-sized pieces into your big application”
  12. Gang of Four • 23 patterns in 3 groups •

    Creational • Structural • Behavioral
  13. Gang of Four Creational Patterns • Abstract Factory • Builder

    • Factory Method • Prototype • Singleton Behavioral Patterns • Chain of Resp. • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy • Template • Visitor Structural Patterns • Adapter • Bridge • Composite • Decorator • Facade • Flyweight • Proxy
  14. Gang of Four Creational Patterns • Abstract Factory • Builder

    • Factory Method • Prototype • Singleton Behavioral Patterns • Chain of Resp. • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy • Template • Visitor Structural Patterns • Adapter • Bridge • Composite • Decorator • Facade • Flyweight • Proxy
  15. Behavioral Patterns • Chain of Resp. • Command • Interpreter

    • Iterator • Mediator • Memento • Observer • State • Strategy • Template • Visitor Structural Patterns • Adapter • Bridge • Composite • Decorator • Facade • Flyweight • Proxy Architectural Patterns • MV* (MVC / MVVM / MVP) • Flux • n-tier • SOA Creational Patterns • Abstract Factory • Builder • Factory Method • Prototype • Singleton Other Patterns • Module • Revealing Module
  16. // TODO 1. Where did Design Patterns come from? 2.

    Software Patterns emerge 3. JavaScript Patterns for Everyday Awesomeness! 4. Large-scale JS Apps
  17. JS Object Patterns /**
 * "Essential JavaScript Design Patterns"
 *

    Copyright Addy Osmani 2014
 * http://creativecommons.org/licenses/by-nc-nd/3.0/
 */
  18. –Stoyan Stefanov, JavaScript Patterns “Unlike other languages, JavaScript doesn’t have

    special syntax for packages, but the module pattern provides the tools to create self-contained decoupled pieces of code, which can be treated as black boxes of functionality…” module pattern
  19. immediately invoked function
 (to create a closure) private variables and

    methods public variables and methods
 (returned from function) module var myNamespace = (function () {
 
 var myPrivateVar, myPrivateMethod;
 
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })();
  20. immediately invoked function
 (to create a closure) private variables and

    methods public variables and methods
 (returned from function) var myNamespace = (function () {
 
 var myPrivateVar, myPrivateMethod;
 
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })(); module
  21. var myNamespace = (function () {
 
 var myPrivateVar, myPrivateMethod;


    
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })(); immediately invoked function
 (to create a closure) private variables and methods public variables and methods
 (returned from function) module
  22. var myNamespace = (function () {
 
 var myPrivateVar, myPrivateMethod;


    
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })(); immediately invoked function
 (to create a closure) private variables and methods public variables and methods
 (returned from function) module
  23. immediately invoked function
 (to create a closure) private variables and

    methods public variables and methods
 (returned from function) module var myNamespace = (function () {
 
 var myPrivateVar, myPrivateMethod;
 
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })();
  24. revealing module var myNamespace = (function () {
 
 var

    myPrivateVar, myPrivateMethod;
 
 // A private counter variable
 myPrivateVar = 0;
 
 // A private function which logs any arguments
 myPrivateMethod = function( foo ) {
 console.log( foo );
 };
 
 return {
 
 // A public variable
 myPublicVar: "foo",
 
 // A public function utilizing privates
 myPublicFunction: function( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 };
 
 })();
  25. revealing module var myNamespace = (function () {
 
 //

    A private counter variable
 var myPrivateVar = 0;
 
 // A private function which logs any arguments
 function myPrivateMethod( foo ) {
 console.log( foo );
 }
 
 // A public function utilizing privates
 function myPublicFunction( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 
 return {
 // A public variable
 myPublicVar: "foo",
 
 // A public function
 myPublicFunction: myPublicFunction
 };
 
 })();
  26. move public methods above return statement return only vars and

    methods that should be public revealing module var myNamespace = (function () {
 
 // A private counter variable
 var myPrivateVar = 0;
 
 // A private function which logs any arguments
 function myPrivateMethod( foo ) {
 console.log( foo );
 }
 
 // A public function utilizing privates
 function myPublicFunction( bar ) {
 
 // Increment our private counter
 myPrivateVar++;
 
 // Call our private method using bar
 myPrivateMethod( bar );
 
 }
 
 return {
 // A public variable
 myPublicVar: "foo",
 
 // A public function
 myPublicFunction: myPublicFunction
 };
 
 })();
  27. module Advantages
 Helps us separate, encapsulate, and organize JS code

    Allows the syntax of our scripts to be more consistent Increases readability Disadvantages
 Private methods can’t be patched or extended
  28. –Addy Osmani, Learning JavaScript Design Patterns “When we put up

    a facade, we present an outward appearance to the world which may conceal a very different reality.” faҫade pattern
  29. Multiple possible implementations, we’re not sure which one this browser

    supports Consolidate to a single method faҫade pattern function addEvent( el,ev,fn ){
 
 if( el.addEventListener ){
 el.addEventListener( ev,fn, false );
 }else if(el.attachEvent){
 el.attachEvent( "on" + ev, fn );
 } else{
 el["on" + ev] = fn;
 }
 
 };
  30. Multiple possible implementations, we’re not sure which one this browser

    supports Consolidate to a single method faҫade pattern function addEvent( el,ev,fn ){
 
 if( el.addEventListener ){
 el.addEventListener( ev,fn, false );
 }else if(el.attachEvent){
 el.attachEvent( "on" + ev, fn );
 } else{
 el["on" + ev] = fn;
 }
 
 };
  31. Multiple possible implementations, we’re not sure which one this browser

    supports Consolidate to a single method faҫade pattern function addEvent( el,ev,fn ){
 
 if( el.addEventListener ){
 el.addEventListener( ev,fn, false );
 }else if(el.attachEvent){
 el.attachEvent( "on" + ev, fn );
 } else{
 el["on" + ev] = fn;
 }
 
 };
  32. The Problem
 Some libraries or apis have very complex interfaces

    Coding directly to a specific lib locks you into that lib Runtimes (browsers) have different implementation details
 (e.g. IE event model vs. other browsers) 
 faҫade
  33. bindReady: function() {
 ...
 if ( document.addEventListener ) {
 //

    Use the handy event callback
 document.addEventListener( “DOMContentLoaded", DOMContentLoaded, false );
 
 // Fallback to window.onload, that will always work
 window.addEventListener( "load", jQuery.ready, false );
 
 // If IE event model is used
 } else if ( document.attachEvent ) {
 
 document.attachEvent( “onreadystatechange", DOMContentLoaded );
 
 // Fallback to window.onload, that will always work
 window.attachEvent( "onload", jQuery.ready );
 ... faҫade pattern Multiple possible implementations, we’re not sure which one this browser supports Consolidate to a single method $(document).ready(..)
  34. bindReady: function() {
 ...
 if ( document.addEventListener ) {
 //

    Use the handy event callback
 document.addEventListener( “DOMContentLoaded", DOMContentLoaded, false );
 
 // Fallback to window.onload, that will always work
 window.addEventListener( "load", jQuery.ready, false );
 
 // If IE event model is used
 } else if ( document.attachEvent ) {
 
 document.attachEvent( “onreadystatechange", DOMContentLoaded );
 
 // Fallback to window.onload, that will always work
 window.attachEvent( "onload", jQuery.ready );
 ... faҫade pattern Multiple possible implementations, we’re not sure which one this browser supports Consolidate to a single method $(document).ready(..)
  35. bindReady: function() {
 ...
 if ( document.addEventListener ) {
 //

    Use the handy event callback
 document.addEventListener( “DOMContentLoaded", DOMContentLoaded, false );
 
 // Fallback to window.onload, that will always work
 window.addEventListener( "load", jQuery.ready, false );
 
 // If IE event model is used
 } else if ( document.attachEvent ) {
 
 document.attachEvent( “onreadystatechange", DOMContentLoaded );
 
 // Fallback to window.onload, that will always work
 window.attachEvent( "onload", jQuery.ready );
 ... faҫade pattern Multiple possible implementations, we’re not sure which one this browser supports Consolidate to a single method $(document).ready(..)
  36. Implementations
 jQuery $.ajax() - wraps different browser implementations into a

    single one with a unified api Angular directive wrapping third party code (e.g. d3 chart) faҫade examples
  37. Advantages
 Simplifies interfaces of objects and environments Reduces repeated code

    Increases readability Disadvantages
 Small performance hit
 faҫade
  38. –Simon Timms, Mastering JavaScript Design Patterns “A mediator will sit

    between the various components and act as a single place in which message routing changes can be made.” mediator pattern
  39. Stardate 91749.10 ReadingPane Boxes EmailList Label ipsum Label ipsum Label

    ipsum Lorem Lorem Lorem Label ipsum Stardate 92799.08 Stardate 92799.08 Stardate 92497.21 Stardate 92455.23 Stardate 92394.01 Stardate 92347.22 Stardate 92299.17 Stardate 92003.06
  40. Stardate 91749.10 ReadingPane Boxes EmailList Label ipsum Label ipsum Label

    ipsum Lorem Lorem Lorem Label ipsum Stardate 92799.08 Stardate 92799.08 Stardate 92497.21 Stardate 92455.23 Stardate 92394.01 Stardate 92347.22 Stardate 92299.17 Stardate 92003.06
  41. Stardate 91749.10 ReadingPane Boxes EmailList Label ipsum Label ipsum Label

    ipsum Lorem Lorem Lorem Label ipsum Stardate 92799.08 Stardate 92799.08 Stardate 92497.21 Stardate 92455.23 Stardate 92394.01 Stardate 92347.22 Stardate 92299.17 Stardate 92003.06
  42. The Problem
 Objects often need a way of communicating with

    each other, but direct communication causes tight coupling Many-to-many relationships in objects can be complicated 
 mediator
  43. Advantages
 Reduces number of communication channels between objects or components

    Promotes loose coupling! Improves code maintenance and makes it easier to refactor down the road Disadvantages
 Single point of failure Possible performance hit mediator
  44. Implementations
 Email client Multi-paned app Scoreboard and Player within a

    game (mediator notifies scoreboard to update when player scores) mediator examples
  45. // TODO 1. Where did Design Patterns come from? 2.

    Software Patterns emerge 3. JavaScript Patterns for Everyday Awesomeness! 4. Large-scale JS Apps
  46. –Addy Osmani, Patterns For Large-Scale JavaScript Application Architecture “If working

    on a significantly large JavaScript application, remember to dedicate sufficient time to planning the underlying architecture that makes the most sense.”
  47. Behavioral Patterns • Chain of Resp. • Command • Interpreter

    • Iterator • Mediator • Memento • Observer • State • Strategy • Template • Visitor Structural Patterns • Adapter • Bridge • Composite • Decorator • Facade • Flyweight • Proxy Architectural Patterns • MV* (MVC / MVVM / MVP) • Flux • n-tier • SOA Creational Patterns • Abstract Factory • Builder • Factory Method • Prototype • Singleton Other Patterns • Module • Revealing Module