JavaScript Design Patterns
-
Upload
derek-brown -
Category
Technology
-
view
544 -
download
1
description
Transcript of JavaScript Design Patterns
![Page 1: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/1.jpg)
JavaScript PatternsAdding Tools to Your Toolbox
/ Derek Brown @derekbrown
![Page 2: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/2.jpg)
QuestionCan you drive a nail into a board using a Phillips-head
screwdriver?
![Page 3: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/3.jpg)
AnswerYep. But it'll suck. Get a hammer, moron.
![Page 4: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/4.jpg)
Why Patterns?Great design patterns are reusable, modular expressions of
what's going on in your code. They allow you to
communicate to other developers simply by the way you
code, in addition to being easily maintainable themselves.
Put simply, patterns are the available tools in the
developer's toolbox.
![Page 5: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/5.jpg)
The Patterns We'll CoverThere are hundreds of design patterns that can be
leveraged for use here in your code base. Ain't nobody got
time for that, so we'll cover only a few that are pretty
different from one another, but are prevalent in
applications, to get a glance at what's out there.
For each pattern, we'll look at the following:
Definition
Code Sample
Advantages & Disadvantages
Common Usage
![Page 6: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/6.jpg)
Module / Revealing ModuleYou are already familiar with this pattern. Trust me. It's one
of the most common patterns on the web.
![Page 7: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/7.jpg)
SingletonThere can be only one....instance of this object.
![Page 8: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/8.jpg)
FacadeA facade is exactly what it sounds like: makeup on a bulldog.
You're covering over complex, ugly things with a simplified
interface for future, more scalable development.
![Page 9: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/9.jpg)
CommandThis pattern is useful for action-oriented objects.
![Page 10: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/10.jpg)
FactoryThe factory pattern lets you encapsulate multiple types of
objects within a categorical constructor.
![Page 11: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/11.jpg)
ObserverThis is a pattern that we've talked about previously, within
the context of Ember. But how can you implement a
publish/subscribe model yourself? And when should you?
![Page 12: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/12.jpg)
DelegateDelegates are a pattern that allow for event-like
communication between components.
![Page 13: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/13.jpg)
Module / Revealing ModuleThis is one of the most fundamental design patterns in the
JavaScript universe. It's primary use is to include both
private and public variables within a single class-like object
while at the same time protecting the private
methods/properties from the application.
Modules accomplish this encapsulation by using closures to
protect the private pieces while allowing the developer to
determine which pieces of the object should be publicly
exposed to the rest of the application.
![Page 14: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/14.jpg)
Module / Revealing Module
var myModule = (function () {
var myProperty = 'Value';
return { getProperty: function () { return myProperty; },
setProperty: function (newValue) { myProperty = newValue; } }; })();
myModule.getProperty(); // Returns 'Value' myModule.setProperty('New Value'); myModule.getProperty(); // Returns 'New Value'
![Page 15: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/15.jpg)
Module / Revealing ModuleMy return object is going to get a bit messy....
![Page 16: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/16.jpg)
Module / Revealing Module var myModule = (function () {
var myProperty = 'Value';
function getProperty () { return myProperty; }
function setProperty (newValue) { myProperty = newValue; }
return { get: getProperty, set: setProperty };
})();
myModule.get(); // Returns 'Value' myModule.set('New Value'); myModule.get(); // Returns 'New Value'
![Page 17: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/17.jpg)
Advantages: ModuleClean, readable, & consistent syntax.
Less clutter in the global namespace.
Allows developers to control scope of properties & methods.
Localization of functions & variables
![Page 18: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/18.jpg)
Disadvantages: ModuleUnit testing can be difficult if the methods aren't exposed.
Private methods are unaccessible.
Can't easily extend private methods.
![Page 19: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/19.jpg)
Common UsageEverything. <\sarcasm>
But really.
![Page 20: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/20.jpg)
SingletonThe singleton pattern is extremely useful if you only one
instance of the object to ever exist. Basically, what occurs
within the Singleton pattern is that you write your object,
and then as a part of that object, you have an additional
method. This function simply checks if an instance of the
object already exists. If it does, use that instance. If not, then
create a new one and store the reference.
![Page 21: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/21.jpg)
Singleton var mySingleton = (function () {
var instance, myProperty = 'Value';
function getProperty () { return myProperty; }
function setProperty (newValue) { myProperty = newValue; }
function initialize () { return { get: getProperty, set: setProperty }; }
return { getInstance: function () {
if ( !instance ) { instance = initialize();
![Page 22: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/22.jpg)
Advantages: SingletonReduced memory usage
Single point of access
Delayed initialization prevents instantiation until required
![Page 23: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/23.jpg)
Disadvantages: SingletonOnce an instance exists, it's difficult to "reset".
Harder to unit test.
![Page 24: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/24.jpg)
Common UsageApplication Instances.
![Page 25: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/25.jpg)
FacadeThe facade pattern is often paired with other patterns to
add an extra layer of security while at the same time
providing a simpler interface to the underlying functionality.
![Page 26: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/26.jpg)
Facade var myFacade = (function () {
var myProperty = 'Value';
function getProperty () { return myProperty; };
function setProperty (newValue) { myProperty = newValue; }
return { get: function () { return getProperty(); }, set: function (newValue) { setProperty(newValue); } };
})();
![Page 27: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/27.jpg)
Advantages: FacadeEnhances security, as internal functions aren't exposed.
Easy to implement
Works well with other design patterns.
Easy to patch internals
Provides a simple public interface
![Page 28: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/28.jpg)
Disadvantages: FacadeIs the cost of implementation really worth the extra layer of
abstraction?
![Page 29: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/29.jpg)
Common UsageOne of the most prevalent uses of the Facade pattern ever:
jQuery
![Page 30: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/30.jpg)
CommandThe command pattern completely separates the
implementation and execution of methods. Usually, in order
to execute a method, you directly invoke the method itself.
The command pattern takes the name of the method to
execute as an argument into an "execute" or "run" method
on the command object, applying the rest of the arguments
list to the function being invoked.
In most programming, objects represent nouns. In the
command pattern, objects are verbs.
![Page 31: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/31.jpg)
Command var myCommand = {
requestData: function (id, attribute) { return 'Data attribute ' + attribute + ' has been requested for object ' },
clearData: function (id, attribute) { return 'The data attribute ' + attribute + ' has been reset for object ' }
}
myCommand.run = function (command) { return myCommand[command.request](command.id, command.attribute) };
/* Alternatively, the run function could look like this, which would pass extra myCommand.run = function (command) { return myCommand[command].apply( myCommand, [].slice.call(arguments, 1)); };
or for argumentless commands, you can go even simpler:
myCommand.run = function (command) {
![Page 32: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/32.jpg)
Advantages: CommandDecouples implementation from execution, which allows for
extensibility while minimizing code changes.
Stacking command objects allows you to cache them, store them in a
history, or otherwise manipulate them. Undo, anyone?
![Page 33: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/33.jpg)
Disadvantages: CommandCounter-intuitive to most OOP practices.
Very limited use to 'verb-centric' applications.
![Page 34: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/34.jpg)
Common UsageCommand Line Interfaces for Node.js
![Page 35: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/35.jpg)
FactoryThe factory pattern is as a interface that can be used to
create objects, usually which belong to a set or category.
The factory takes in the attributes of the object to be
created, and then returns a new instance of our object.
![Page 36: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/36.jpg)
Factoryfunction Manager ( config ) { this.name = config.name || 'Michael Scott'; this.role = config.role || 0; this.user = config.user || 'MichaelScott123';}
function Contributor ( config ) { this.name = config.name || 'Bob Smith'; this.role = config.role || 1; this.user = config.user || 'BobSmith123'; this.mngr = config.mngr || 'MichaelScott123';}
function Contractor ( config ) { this.name = config.name || 'John Doe'; this.role = config.role || 2; this.user = config.user || 'JohnDoe123'; this.mngr = config.mngr || 'MichaelScott123'; this.term = config.term || '6 months';}
function WorkerFactory() {}
WorkerFactory.prototype.employeeClass = Contributor;WorkerFactory.prototype.hireSomeone = function ( config ){
![Page 37: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/37.jpg)
Advantages: FactoryAllows the sharing of properties across multiple objects.
Extremely useful when object or component setup is complex.
Also useful when you need to generate different instances based on
context.
![Page 38: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/38.jpg)
Disadvantages: FactoryFairly complex for smaller applications.
Garbage collection can have high overhead.
Can introduce problems with unit testing.
![Page 39: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/39.jpg)
Common UsageAddress Book (contacts), To-Do App (tasks)
![Page 40: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/40.jpg)
ObserverIn the observer pattern, a type of publish-subscribe pattern,
there is an object (often called the subject or observable)
that notifies other objects (observers) of any changes that
occur to the state of the subject. The observers are often
maintained in a list on the observable, to be iterated upon
when a change occurs.
![Page 41: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/41.jpg)
Observer var observer = { addSubscriber: function (callback) { this.subscribers[this.subscribers.length] = callback; },
removeSubscriber: function (callback) { for (var i = 0; i < this.subscribers.length; i++) { if (this.subscribers[i] === callback) { delete(this.subscribers[i]); } } },
publish: function (what) { for (var i = 0; i < this.subscribers.length; i++) { if (typeof this.subscribers[i] === 'function') { this.subscribers[i](what); } } },
makePublisher: function (o) { // turns an object into a publisher for (var i in this) { o[i] = this[i]; o.subscribers = [];
Source: For another example using Ember's implementation, check out Chad Hietala's ConnectionViewer repository.
![Page 42: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/42.jpg)
Advantages: ObserverFaciliates application-level thinking.
Removes direct relationships that are often unnecessary.
Can relate objects without tightly coupling them.
![Page 43: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/43.jpg)
Disadvantages: ObserverThere is no way to know if the other end of the telephone is still
listening.
Subscribers aren't aware of one another.
![Page 44: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/44.jpg)
Common UsageYUI Custom Events. Ember Observables.
![Page 45: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/45.jpg)
DelegateIn the delegate pattern, an object (the delegator) offloads a
task to an associated helper object (the delegate), rather
than performing the task itself. Often times, this is within an
MVC framework or architecture, involving a Controller as
the delegator.
![Page 46: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/46.jpg)
Delegatevar ViewClass = function () { return { init : function (el) { var $el = $(el);
// REQUIRED: delegate should have a viewWasClicked method implemented $el.on('click', this.delegate.viewWasClicked); }, delegate : null };};
var ControllerClass = function () { return { viewWasClicked : function (e) { console.log('I was called!'); } }};
var controller = new ControllerClass();var view = new ViewClass();
view.delegate = controller;view.init(document.getElementById('myHeader'));
Source: David Drew's fantastic article on implementing Objective-C Delegates in JavaScript
![Page 47: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/47.jpg)
Advantages: DelegateDelegation allows for loose coupling without global eventing.
Easy to maintain structure within an application.
![Page 48: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/48.jpg)
Disadvantages: DelegateNo well-structured way to enforce delegation attachment.
Assignment of delegate takes place prior to initialization.
![Page 49: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/49.jpg)
Common UsageMost MVC frameworks at least involve delegation in their
design in some regard, due to the interaction between
models, views, and controllers.
![Page 50: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/50.jpg)
Helpful Resources & ReadingLearning JavaScript Design Patterns by Addy Osmani
JavaScript Patterns on GitHub
Carl Danley: JavaScript Design Patterns
JavaScript Design Patterns on Adobe DevNet
Pro JavaScript Design Patterns
Zakas on the Factory Pattern
JavaScript Design Patterns
![Page 51: JavaScript Design Patterns](https://reader033.fdocuments.net/reader033/viewer/2022051616/554c4d4bb4c905452e8b45b6/html5/thumbnails/51.jpg)
Fin.