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.
In this presentation, I review a few common patterns, their advantages/disadvantages, and how they can be implemented.
The source for this presentation can be found here: https://github.com/derekbrown/designpatterns
4. 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.
5. The Patterns We'll Cover
There 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
8. Facade
A 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.
10. Factory
The factory pattern lets you encapsulate multiple types of
objects within a categorical constructor.
11. Observer
This 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?
13. Module / Revealing Module
This 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.
17. Advantages: Module
Clean, readable, & consistent syntax.
Less clutter in the global namespace.
Allows developers to control scope of properties & methods.
Localization of functions & variables
18. Disadvantages: Module
Unit testing can be difficult if the methods aren't exposed.
Private methods are unaccessible.
Can't easily extend private methods.
20. Singleton
The 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.
21. Singleton
vrmSnltn=(ucin( {
a yigeo
fnto )
vrisac,
a ntne
mPoet ='au'
yrpry
Vle;
fnto gtrpry( {
ucin ePoet )
rtr mPoet;
eun yrpry
}
fnto strpry(eVle {
ucin ePoet nwau)
mPoet =nwau;
yrpry
eVle
}
fnto iiilz ( {
ucin ntaie )
rtr {
eun
gt gtrpry
e: ePoet,
st strpry
e: ePoet
}
;
}
rtr {
eun
gtntne fnto ( {
eIsac: ucin )
i (!ntne){
f
isac
isac =iiilz(;
ntne
ntaie)
25. Facade
The 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.
26. Facade
vrmFcd =(ucin( {
a yaae
fnto )
vrmPoet ='au'
a yrpry
Vle;
fnto gtrpry( {
ucin ePoet )
rtr mPoet;
eun yrpry
}
;
fnto strpry(eVle {
ucin ePoet nwau)
mPoet =nwau;
yrpry
eVle
}
rtr {
eun
gt fnto ( {rtr gtrpry) }
e: ucin )
eun ePoet(; ,
st fnto (eVle {strprynwau) }
e: ucin nwau)
ePoet(eVle;
}
;
}(;
))
27. Advantages: Facade
Enhances 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
30. Command
The 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.
31. Command
vrmCmad={
a yomn
rqetaa fnto (d atiue {
eusDt: ucin i, trbt)
rtr 'aaatiue'+atiue+'hsbe rqetdfrojc '
eun Dt trbt
trbt
a en euse o bet
}
,
ceraa fnto (d atiue {
laDt: ucin i, trbt)
rtr 'h dt atiue'+atiue+'hsbe rstfrojc '
eun Te aa trbt
trbt
a en ee o bet
}
}
mCmadrn=fnto (omn){
yomn.u
ucin cmad
rtr mCmadcmadrqet(omn.d cmadatiue
eun yomn[omn.eus]cmadi, omn.trbt)
}
;
/
*
Atraiey ternfnto cudlo lk ti,wihwudps eta
lentvl, h u ucin ol ok ie hs hc ol as xr
mCmadrn=fnto (omn){
yomn.u
ucin cmad
rtr mCmadcmad.pl(mCmad [.lc.alagmns 1)
eun yomn[omn]apy yomn, ]siecl(ruet, );
}
;
o fragmnls cmad,yucng ee smlr
r o ruetes omns o a o vn ipe:
mCmadrn=fnto (omn){
yomn.u
ucin cmad
32. Advantages: Command
Decouples 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?
35. Factory
The 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.
37. Advantages: Factory
Allows 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.
40. Observer
In 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.
41. Observer
vrosre ={
a bevr
adusrbr fnto (alak {
dSbcie: ucin clbc)
ti.usrbr[hssbcieslnt]=clbc;
hssbciesti.usrbr.egh
alak
}
,
rmvSbcie:fnto (alak {
eoeusrbr ucin clbc)
fr(a i=0 i<ti.usrbr.egh i+ {
o vr
;
hssbcieslnt; +)
i (hssbciesi ==clbc){
f ti.usrbr[] = alak
dlt(hssbciesi)
eeeti.usrbr[];
}
}
}
,
pbih fnto (ht {
uls: ucin wa)
fr(a i=0 i<ti.usrbr.egh i+ {
o vr
;
hssbcieslnt; +)
Source: For another example using Ember's implementation, check out Chad Hietala's Connection
i ( y e f t i . u s r b rrepository. ' u c i n ) {
f tpo hssbciesi == fnto'
Viewer [ ] =
ti.usrbr[]wa)
hssbciesi(ht;
}
}
}
,
mkPbihr fnto (){/ trsa ojc it apbihr
aeulse: ucin o
/ un n bet no
ulse
fr(a ii ti){
o vr
n hs
oi =ti[]
[]
hsi;
osbcies=[;
.usrbr
]
45. Delegate
In 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.
46. Delegate
vrVeCas=fnto ( {
a iwls
ucin )
rtr {
eun
ii :fnto (l {
nt
ucin e)
vr$l=$e)
a e
(l;
/ RQIE:dlgt sol hv aveWslce mto ipee
/ EURD eeae hud ae
iwaCikd ehd mlmn
$lo(cik,ti.eeaeveWslce)
e.n'lc' hsdlgt.iwaCikd;
}
,
dlgt :nl
eeae
ul
}
;
}
;
vrCnrleCas=fnto ( {
a otolrls
ucin )
rtr {
eun
veWslce :fnto (){
iwaCikd
ucin e
Source: David Drew's fantastic article on implementing Objective-C Delegates in JavaScript
cnoelg' wscle!)
osl.o(I a ald';
}
}
}
;
vrcnrle =nwCnrleCas)
a otolr
e otolrls(;
vrve =nwVeCas)
a iw
e iwls(;
ve.eeae=cnrle;
iwdlgt
otolr
ve.ntdcmn.eEeetyd'yedr);
iwii(ouetgtlmnBI(mHae')
49. Common Usage
Most MVC frameworks at least involve delegation in their
design in some regard, due to the interaction between
models, views, and controllers.
50. Helpful Resources & Reading
Learning 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