This document discusses several common JavaScript design patterns including Singleton, Factory, Module, Decorator, Command, and Observer patterns. It provides descriptions and code examples for each pattern. The Singleton pattern ensures a class only has one instance and provides a global access point. Factory patterns are used for object creation. The Module pattern provides private and public encapsulation for classes. The Decorator pattern attaches additional responsibilities to objects dynamically. The Command pattern encapsulates requests as objects, and the Observer pattern allows objects to watch other objects for changes.
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. 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.
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. Types of Design Pattern
• Creational
– Object creation.
• Structural
– Relationship between entities.
• Behavioral
– Communication between objects.
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. 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. 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
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.
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. 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. 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. 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.
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. Factory Patterns
(Abstract Factory Pattern)
• Abstract Factory offers the interface for creating a
family of related objects, without explicitly
specifying their classes.
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. 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. 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. 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. 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.
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. 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. 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.
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.
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.
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.
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.
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;
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.
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. 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...
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. 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)