Skip to content

Instantly share code, notes, and snippets.

@sukhmeet2390
Created September 6, 2016 10:20
Show Gist options
  • Save sukhmeet2390/5dd0ba38286f0625f89b1c0e98337819 to your computer and use it in GitHub Desktop.
Save sukhmeet2390/5dd0ba38286f0625f89b1c0e98337819 to your computer and use it in GitHub Desktop.
/* Module pattern
- Helps in both scoping private and public scoping
- Avoids global namespace
- Con: Privates are not easily testable
*/
var myModule = (function (){
var private1;
return {
attr1 : attr1,
fn1: function(){},
....
....
}
})();
myModule.fn1();
// Declatiion using IIFE
(function(){
var private1;
function myModule() {
attr1: attr1,
fun1: function(){
}
}
window.myModule = myModule;
})()
var mod = new myModule();
mod.fun1();
/*
Revealing Module Pattern
Similar to module but clear definition of what to expose
*/
(function(){
var private1;
function something(){
...
}
function myModule() {
attr1: attr1,
fun1: something
}
window.myModule = myModule;
})()
var mod = new myModule();
mod.fun1();
var MyModule = ( function( window, undefined ) {
function myMethod() {
alert( 'my method' );
}
function myOtherMethod() {
alert( 'my other method' );
}
// explicitly return public methods when this object is instantiated
return {
someMethod : myMethod,
someOtherMethod : myOtherMethod
};
} )( window );
MyModule.someMethod();
/* Singleton pattern
- Restricts instantiation to 1 object, hence low memory foot print
- Single point of acess
- Can do lazy instantiation
- Hard to do unit tests,
- Not so good
*/
var mySingleton = ( function( window, undefined ) {
var instance = null;
// revealing module pattern that handles initialization of our new module
function Module() {
function myMethod() {
alert( 'my method' );
}
return {
someMethod : myMethod
};
}
// handles the prevention of additional instantiations
function getInstance() {
if( ! instance ) {
instance = new Module();
}
return instance;
}
return {
getInstance : getInstance
};
} )( window );
mySingleton.getInstance().someMethod();
/*
Observer pattern / PubSub
- This pattern implements a single object (the subject) that maintains a reference to a collection of objects (known as "observers") and broadcasts notifications when a change to state occurs.
- When we don't want to observe an object, we simply remove it from the collection of objects being observed.
- The observer pattern is similar to both the pub/sub implementation and the mediator pattern but still different in purpose
- Excellent at decoupling objects which often promotes smaller, reusable components
- Checking the integrity of your application can become difficult
- What subscribes and what not can be tedious
*/
var pubsub = {};
(function(myObject) {
// Storage for topics that can be broadcast or listened to
var topics = {};
// An topic identifier
var subUid = -1;
// Publish or broadcast events of interest with a specific topic name and arguments such as the data to pass along
myObject.publish = function( topic, args ) {
if ( !topics[topic] ) {
return false;
}
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func( topic, args );
}
return this;
};
// Subscribe to events of interest with a specific topic name and a callback function, to be executed
// when the topic/event is observed
myObject.subscribe = function( topic, func ) {
if (!topics[topic]) {
topics[topic] = [];
}
var token = ( ++subUid ).toString();
topics[topic].push({
token: token,
func: func
});
return token;
};
// Unsubscribe from a specific topic, based on a tokenized reference to the subscription
myObject.unsubscribe = function( token ) {
for ( var m in topics ) {
if ( topics[m] ) {
for ( var i = 0, j = topics[m].length; i < j; i++ ) {
if ( topics[m][i].token === token ) {
topics[m].splice( i, 1 );
return token;
}
}
}
}
return this;
};
}( pubsub ));
var subscription = pubsub.subscribe( "inbox/newMessage", messageLogger );
pubsub.publish( "inbox/newMessage", "hello world!" );
pubsub.publish( "inbox/newMessage", ["test", "a", "b", "c"] );
(function($) {
var o = $({});
$.subscribe = function() {
o.on.apply(o, arguments);
};
$.unsubscribe = function() {
o.off.apply(o, arguments);
};
$.publish = function() {
o.trigger.apply(o, arguments);
};
}(jQuery));
/* Facade pattern
The purpose of the facade pattern is to conceal the underlying complexity of the code by using an anonymous function as an extra layer.
Internal subroutines are never exposed but rather invoked through a facade which makes this pattern secure in that it never exposes anything
to the developers working with it.
- Enhances security for your web application
- Makes it easy to patch internals
- Provides a simpler public interface
- Proven useful for other major libraries such as jQuery
*/
// a simple facade that masks the various browser-specific methods
function addEvent( element, event, callback ) {
if( window.addEventListener ) {
element.addEventListener( event, callback, false );
} else if( document.attachEvent ) {
element.attachEvent( 'on' + event, callback );
} else {
element[ 'on' + event ] = callback;
}
}
var MyModule = ( function( window, undefined ) {
// revealing module pattern
function MyModule() {
function someMethod() {
alert( 'some method' );
}
function someOtherMethod() {
alert( 'some other method' );
}
// expose publicly available methods
return {
// in our normal revealing module pattern, we'd do the following:
someMethod : someMethod,
// in the facade pattern, we mask the internals so no one has direct access by doing this:
someMethod : function() {
someMethod();
}
};
}
} )( window )
/* Factory Pattern
This pattern focuses on object creation but differs from other patterns in the creation category in that it does not require a constructor function.
The factory pattern generally supplies an interface for developers to create new objects through the use of the factory rather than invoking the new operator on an object.
- Makes complex object creation easy through an interface that can bootstrap this process for you
- Great for generating different objects based on the environment
- Unit testing can be difficult as a direct result of the object creation process being hidden by the factory methods
- When applied to the wrong type of problem, this pattern can introduce an unnecessarily great deal of complexity to an application.
*/
function CarDoor( options ) {
this.color = options.color || 'red';
this.side = options.side || 'right';
this.hasPowerWindows = options.hasPowerWindows || true;
}
function CarSeat( options ) {
this.color = options.color || 'gray';
this.material = options.material || 'leather';
this.isReclinable = options.isReclinable || true;
}
function CarPartFactory() {}
CarPartFactory.prototype.createPart = function createCarPart( options ) {
var parentClass = null;
if( options.partType === 'door' ) {
parentClass = CarDoor;
} else if( options.partType === 'seat' ) {
parentClass = CarSeat;
}
if( parentClass === null ) {
return false;
}
return new parentClass( options );
}
// example usage
var myPartFactory = new CarPartFactory();
var seat = myPartFactory.createPart( {
partType : 'seat',
material : 'leather',
color : 'blue',
isReclinable : false
} );
// outputs: true
console.log( seat instanceof CarSeat );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment