Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Javascript Common Design Patterns

Javascript Common Design Patterns

  • Soyez le premier à commenter

Javascript Common Design Patterns

  1. 1. JavaScript Design Patterns 2014 – Pham Tung
  2. 2. Contents • What is Design Pattern? • Why Design Pattern? • Types of Design Pattern • Explore some patterns 1. Singleton Pattern 2. Factory Pattern 3. Module Pattern 4. Decorator Pattern 5. Command Pattern 6. Observer Pattern
  3. 3. What is Design Pattern • A general reusable solution to a commonly occurring problem in software design. • Not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations.
  4. 4. Why Design Patterns Building diagram? No need!
  5. 5. Why Design Patterns
  6. 6. Why Design Patterns • To design a new software system quickly and efficiently. • To understand a existing software system. • Speed up the development process by providing tested, proven development paradigms. • Help to prevent subtle issues that can cause major problems, code readability. • Allow developers to communicate using well- known, well understood names for software interactions.
  7. 7. Types of Design Pattern • Creational – Object creation. • Structural – Relationship between entities. • Behavioral – Communication between objects.
  8. 8. Periodic Table of Patterns
  9. 9. Patterns we are going to explore Creational ● Singleton ● Factory Structural ● Decorator Behavioral ● Command ● Observer ● Module
  10. 10. Singleton Pattern Creational: 1
  11. 11. Singleton Pattern • Ensure a class has only one instance, and provide a global point of access to it. • Encapsulated “just-in-time initialization” or “initialization on first use”. • Reduce the need for global variables which is particularly important in JavaScript because it limits namespace pollution and associated risk of name collisions. • The Module pattern is JavaScript's manifestation of the Singleton pattern.
  12. 12. Singleton Pattern 1. var Singleton = (function () { 2. var instance; 3. function createInstance() { 4. var object = new Object("I am the instance"); 5. return object; 6. } 7. return { 8. getInstance: function () { 9. if (!instance) { 10. instance = createInstance(); 11. } 12. return instance; 13. } 14. }; 15. })(); 16. var instance1 = Singleton.getInstance(); 17. var instance2 = Singleton.getInstance(); 18. alert("Same instance? " + (instance1 === instance2));
  13. 13. Singleton Pattern 1. function MySingletonClass() { 2. if ( arguments.callee._singletonInstance ) 3. return arguments.callee._singletonInstance; 4. arguments.callee._singletonInstance = this; 5. this.Foo = function() { 6. // ... 7. } 8. } 9. var a = new MySingletonClass() 10. var b = MySingletonClass() 11. console.log( a === b ); // prints: true
  14. 14. Factory Patterns Creational: 2
  15. 15. Factory Patterns Classes should be open for extension, but closed for modification. Dependency Inversion Principle Depend upon abstractions. Do not depend upon concrete classes.
  16. 16. Factory Patterns ● Simple Factory ● Factory Method ● Abstract Factory
  17. 17. Factory Patterns I want to buy a Doraemon book. Oh, yes yes! Please send me that Rabbit book.
  18. 18. Factory Patterns
  19. 19. Factory Patterns
  20. 20. Factory Patterns OMG! IS IT FUNNY!
  21. 21. Factory Patterns (Simple Factory) ● Is a class with a public static method which will actually do the object creation task according to the input it gets.
  22. 22. Factory Patterns (Simple Factory) function orderBook(var type){ var book; if (type === 'comic') { book = new ComicBook(); } else if (type === 'history') { book = new HistoryBook(); } else if (type === 'Science') { book = new ScienceBook(); } book.prepare(); book.box(); return book; } We need to modify the entire code whenever a new type is added. And this code is consistent. We don’t need to make a change. But only this highlight code need to be modified.
  23. 23. Factory Patterns (Simple Factory) function orderBook(type){ var book; book.prepare(); book.box(); return book; } var Factory = { getBook : function (type){ var book; if (type === 'comic') { book = new ComicBook(); } else if (type === 'history') { book = new HistoryBook(); } else if (type === 'Science') { book = new ScienceBook(); } return book; } }; book = Factory.getBook(type) So, why don’t we move this mess to another place?
  24. 24. Factory Patterns (Factory Method Pattern) • Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory lets a class defer instantiation to subclasses.
  25. 25. Factory Patterns (Factory Method Pattern)
  26. 26. Factory Patterns (Factory Method Pattern) function BookFactory(){ this.getBook = function (type){ var book; if (type === 'comic') { book = new ComicBook(); } else if (type === 'hisoty') { book = new HistoryBook(); } else if … return book; } } var factory = new BookFactory(); var book = factory.getBook( 'comic');
  27. 27. Factory Patterns (Abstract Factory Pattern) • Abstract Factory offers the interface for creating a family of related objects, without explicitly specifying their classes.
  28. 28. Factory Patterns (Abstract Factory Pattern)
  29. 29. Factory Patterns (Abstract Factory Pattern)
  30. 30. Factory Patterns (Abstract Factory Pattern) function EnglishBookFactory(){ this.getBook = function(type){ // … return book; }; this.getNewspaper = function(){ // … return newspaper; }; } function VietnameseBookFactory(){ // … } var factory = new EnglishBookFactory(); var store = new XyzBookStore(factory); store.comeIntoOperations();
  31. 31. Factory Patterns Create only one product. Exposes a method to the client for creating the object. Factory Method Abstract Factory Creating families of related or dependent products. Expose a family of related objects which may consist of these Factory methods. 2 1
  32. 32. Factory Patterns Hides the construction of single object. Uses inheritance and relies on derived class or sub class to create object. Hides the construction of a family of related objects. Uses composition to delegate responsibility of creating object to another class. Factory Method Abstract Factory 3 4
  33. 33. Factory Patterns Differences (when to use): ● Factory Method ○ There is a need to decouple a client from a particular product that it uses ○ To relieve a client of responsibility for creating and configuring instances of a product. ● Abstract Factory ○ Clients must be decoupled from product classes. Especially useful for program configuration and modification. ○ Can also enforce constraints about which classes must be used with others.
  34. 34. Factory Patterns • When To Use: – When your object's setup requires a high level of complexity. – When you need to generate different instances depending on the environment. – When you're working with many small objects that share the same properties. – When composing classes with instances of other classes that need only satisfy an API contract (aka, duck typing) to work. This is useful for decoupling.
  35. 35. Module Pattern Creational, Structural: 3
  36. 36. Module Pattern function private members public members object
  37. 37. Module Pattern function private members public members objectreturn
  38. 38. Module Pattern public members object
  39. 39. Module Pattern public members Module Closure private members
  40. 40. Module Pattern • Provide both private and public encapsulation for classes. • Emulate the concept of classes: able to include both public/private methods and variables inside a single object, thus shielding particular parts from the global scope. ☛ Reduce names conflicting with other functions defined in additional scripts on the page.
  41. 41. Module Pattern 1. var TestModule = (function () { 2. var counter = 0; // private member 3. return { 4. incrementCounter: function () { 5. return counter++; 6. }, 7. resetCounter: function () { 8. console.log('counter value prior to reset:' + counter); 9. counter = 0; 10. } 11. }; 12. })(); 13. // test 14. TestModule.incrementCounter(); 15. TestModule.resetCounter();
  42. 42. Module Pattern testModule.printCounter = function(){ console.log(counter); }; 1. var testModule = (function () { 2. var counter = 0; // private member 3. return { 4. incrementCounter: function () { ... }, 5. resetCounter: function () { ... } 6. }; 7. })(); What will happen if I dynamically add a new function to the testModule variable. Like this.
  43. 43. Module Pattern WTF testModule.printCounter = function(){ console.log(counter); }; testModule.printCounter();
  44. 44. Module Pattern • Advantages – Cleaner for developers coming from an object-oriented background than the idea of true encapsulation. – Supports private data. • Disadvantages – Hard to change visibility of members. – Can't access private members in methods that are added to the object at a later point (dynamically add method). – Inability to create automated unit tests for private members and additional complexity.
  45. 45. Decorator Pattern Structural: 4
  46. 46. Decorator Pattern Classes should be open for extension, but closed for modification. Open-Closed Principle Classes should be open for extension, but closed for modification.
  47. 47. Decorator Pattern 5 $ 7 $ DecoratorComponent
  48. 48. Decorator Pattern 7 $
  49. 49. Decorator Pattern 7 $
  50. 50. Decorator Pattern 7 $ Waiter: NOT BAD!LIKE A BOSS
  51. 51. Decorator Pattern 99 $ 29 $ 89 $7 $ Waiter: Here is your bill, sir 7 + 89 + 99 + 29 = 224 $
  52. 52. Decorator Pattern WormChickenRice WormRice ChickenWormRice EggRice WormEggRice ChickenEggRice ScorpionEggRice ChickenWormEggRice ScorpionRice BeerChickenEggRice ChickenEggRice BeerEggRice ChickenScorpionRice Way 1:
  53. 53. Decorator Pattern Beer (+ 29$) Chicken (+99$) Worm (+89$) Rice (7$) Way 2:
  54. 54. Decorator Pattern • Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. • Multiple decorators can add or override functionality to the original object.
  55. 55. Decorator Pattern
  56. 56. Decorator Pattern function Rice(){ this.cost = 7; } function WormDecorator(rice){ rice.cost += 89; } function ChickenDecorator(rice){ rice.cost += 99; } function BeerDecorator(rice){ rice.cost += 29; } var rice = new Rice(); WormDecorator(rice); ChickenDecorator(rice); BeerDecorator(rice); alert(rice.cost); // 224
  57. 57. Command Pattern Behavioral: 5
  58. 58. Command Pattern • Encapsulate requests/actions as objects. • Command objects allow for loosely coupled systems by separating the objects that issue a request from the objects that actually process the request. • These requests are called events and the code that processes the requests are called event handlers.
  59. 59. Command Pattern
  60. 60. Command Pattern - ConcreteCommand: implementing the Execute method by invoking the corresponding operations on Receiver. - Client: creates a ConcreteCommand object and sets its receiver. - Invoker: asks the command to carry out the request. - Receiver: knows how to perform the operations;
  61. 61. Command Pattern CHÉÉÉÉÉM 4 5 2 1 3
  62. 62. Command Pattern Receiver Invoker Prisoner Client Command CHÉÉÉÉÉM
  63. 63. Command Pattern
  64. 64. Command Pattern // Receiver. function Sword() { this.cut = function() { console.log("Sword: YAAAA! YOU'RE DEAD!"); } } // Command. function CutCommand(sword){ this.execute = function() { sword.cut(); } } // Invoker (may have a lot of commands) function Executioner() { this.cutHead = function(command) { command.execute(); } } // Client function King() { this.run = function(){ var sword = new Sword(); var command = new CutCommand (sword); var executioner = new Executioner(); executioner.cutHead(command); } } (new King()).run(); DEMO
  65. 65. Command Pattern 1. var Agent = { 2. sayHello: function(name) { alert("Hello " + name); }, 3. sayGoodbye: function(name) { alert("Good bye " + name); }, 4. execute: function (name) { 5. return Agent[name] && Agent[name].apply(Agent, [].slice.call(arguments, 1)); 6. } 7. }; 8. Agent.execute("sayHello", "Bill");
  66. 66. Command Pattern 1. var Agent = { 2. sayHello: function(name) { alert("Hello " + name); }, 3. sayGoodbye: function(name) { alert("Good bye " + name); }, 4. execute: function (name) { 5. return Agent[name] && Agent[name].apply(Agent, [].slice.call(arguments, 1)); 6. } 7. }; 8. Agent.execute("sayHello", "Bill"); It seems I have and will never use this pattern in Javascript. Oh, really?
  67. 67. Command Pattern var button = document.getElementById('myBtn'); // add event listener button.addEventListener('click', function(event) { closeWindow(); }); ... What about this?
  68. 68. Command Pattern var button = document.getElementById('myBtn'); // add event listener button.addEventListener('click', function(event) { closeWindow(); }); ...
  69. 69. Command Pattern Command Pattern Event Driven Command object Receiver Invoker Source Event object Target object
  70. 70. Command Pattern http://en.wikipedia.org/wiki/Command_pattern Command Pattern Event Driven Command object Receiver Invoker Source Event object Target object
  71. 71. Command Pattern Client Server Add Update Delete Normal way
  72. 72. Server Command Pattern Client Update Invoker Update
  73. 73. Observer Pattern (Publish/Subscribe pattern) Behavioral: 6
  74. 74. Observer Pattern Hello, I’m Putin. I’d like to make an annual subscription. register/subscribe Subject Aye aye sir.
  75. 75. Observer Pattern Observers ONE TO MANY RELATIONSHIP Subject
  76. 76. Observer Pattern Observers publish Subject
  77. 77. Observer Pattern Observers I want to cancel my subscription ‘cause I’m tired to death. Subject
  78. 78. Observer Pattern Observers Subject Kicker OK, take care, sir.
  79. 79. Observer Pattern • Allows an object (subscriber or observer) to watch another object (publisher or subject). • Subscribers are able to register/unregister (subscribe/unsubscribe) to receive topic notifications from the publisher. • Publisher can notify observers by broadcasting (publishing) a notification to each observer.
  80. 80. Observer Pattern
  81. 81. Observer Pattern
  82. 82. Observer Pattern function Subject() { this.observers = []; } Subject.prototype = { subscribe: function(observer) { this.observers.push(observer); }, unsubscribe: function(name) { // remove observer from subscribers }, notify: function(message) { for (var i =0; i < this.observers.length; i++) { this.observers[i].callback(message); } } }; function Observer(name) { this.name = name; this.callback = function(message){ console.log(message) }; } // Here's where it gets used. var subject = new Subject(); subject.subscribe(new Observer("Putin")); subject.subscribe(new Observer("Mary")); subject.subscribe(new Observer("Binladen")); subject.notify('Hello!');
  83. 83. Observer Pattern <input id='button1' type='button' value='Publish'> <input class='subscriber' type='text'> <input class='subscriber' type='text'> $(function(){ function publish(){ $('.subscriber').trigger('/getnews', 'Hello!'); } $('.subscriber').on('/getnews', function(event, message){ this.value = message; }); $('#button1').click(publish); }); Javascript (jQuery): More example: http://jsfiddle.net/rajeshpillai/xQkXk/22/
  84. 84. Observer Pattern • The power of Loose Coupling – The only thing the subject knows about an observer is that it implements a certain interface. – We can add new observers at any time. – We never need to modify the subject to add new types of observers. – We can reuse subjects or observers independently of each other. – Changes to either the subjects or an observer will no affect the other.
  85. 85. Observer Pattern I found that the Observer pattern is so much like the Event-driven approach. Are they the same? Staff Staff Staff Boss notify Hmm...
  86. 86. Observer Pattern Staff Staff Staff Event Boss Well, the main difference between them is the word “Event”.
  87. 87. Observer Pattern Staff Staff Staff Event Boss When Boss provides the instruction, the event will be responsible for transferring it to staff. And Boss doesn’t care who the hell will receive his instruction.
  88. 88. Observer Pattern As you well know, Leader works closely to the others... In Observer, Leader knows all who will receive his instruction. Member (Observer) Member (Observer) Member (Observer) Leader (Subject)
  89. 89. Observer Pattern So, Event-driven is more loose coupling than Observer pattern? Yep! And actually, no one prevents you to implement Observer using Event-drivent. Member (Observer) Member (Observer) Member (Observer) Leader (Subject)
  90. 90. References Finally 7
  91. 91. References 1. Learning JavaScript Design Patterns - Addy Osmani 2. Head First Design Patterns - Eric Freeman & Elisabeth Freeman with Kathy Sierra & Bert Bates 3. OODesign - oodesign.com 4. Javascript Design Pattern - ww.dofactory.com/javascript-pattern.aspx
  92. 92. The end! Thank you for your attention

×