Last active
February 22, 2020 18:27
-
-
Save ilanl/c2205793577468c997441bd88beaf94f to your computer and use it in GitHub Desktop.
design patterns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Constructor | |
function Car( model, year, miles ) { | |
this.model = model; | |
this.year = year; | |
this.miles = miles; | |
this.toString = function () { | |
return this.model + " has done " + this.miles + " miles"; | |
}; | |
} | |
// Usage: | |
// We can create new instances of the car | |
var civic = new Car( "Honda Civic", 2009, 20000 ); | |
var mondeo = new Car( "Ford Mondeo", 2010, 5000 ); | |
// and then open our browser console to view the | |
// output of the toString() method being called on | |
// these objects | |
console.log( civic.toString() ); | |
console.log( mondeo.toString() ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var basketModule = (function () { | |
// privates | |
var basket = []; | |
function doSomethingPrivate() { | |
//... | |
} | |
function doSomethingElsePrivate() { | |
//... | |
} | |
// Return an object exposed to the public | |
return { | |
// Add items to our basket | |
addItem: function( values ) { | |
basket.push(values); | |
}, | |
// Get the count of items in the basket | |
getItemCount: function () { | |
return basket.length; | |
}, | |
// Public alias to a private function | |
doSomething: doSomethingPrivate, | |
// Get the total value of items in the basket | |
getTotal: function () { | |
var q = this.getItemCount(), | |
p = 0; | |
while (q--) { | |
p += basket[q].price; | |
} | |
return p; | |
} | |
}; | |
})(); | |
// basketModule returns an object with a public API we can use | |
basketModule.addItem({ | |
item: "bread", | |
price: 0.5 | |
}); | |
basketModule.addItem({ | |
item: "butter", | |
price: 0.3 | |
}); | |
// Outputs: 2 | |
console.log( basketModule.getItemCount() ); | |
// Outputs: 0.8 | |
console.log( basketModule.getTotal() ); | |
// However, the following will not work: | |
// Outputs: undefined | |
// This is because the basket itself is not exposed as a part of our | |
// public API | |
console.log( basketModule.basket ); | |
// This also won't work as it only exists within the scope of our | |
// basketModule closure, but not in the returned public object | |
console.log( basket ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ObserverList(){ | |
this.observerList = []; | |
} | |
ObserverList.prototype.add = function( obj ){ | |
return this.observerList.push( obj ); | |
}; | |
ObserverList.prototype.count = function(){ | |
return this.observerList.length; | |
}; | |
ObserverList.prototype.get = function( index ){ | |
if( index > -1 && index < this.observerList.length ){ | |
return this.observerList[ index ]; | |
} | |
}; | |
ObserverList.prototype.indexOf = function( obj, startIndex ){ | |
var i = startIndex; | |
while( i < this.observerList.length ){ | |
if( this.observerList[i] === obj ){ | |
return i; | |
} | |
i++; | |
} | |
return -1; | |
}; | |
ObserverList.prototype.removeAt = function( index ){ | |
this.observerList.splice( index, 1 ); | |
}; | |
function Subject(){ | |
this.observers = new ObserverList(); | |
} | |
Subject.prototype.addObserver = function( observer ){ | |
this.observers.add( observer ); | |
}; | |
Subject.prototype.removeObserver = function( observer ){ | |
this.observers.removeAt( this.observers.indexOf( observer, 0 ) ); | |
}; | |
Subject.prototype.notify = function( context ){ | |
var observerCount = this.observers.count(); | |
for(var i=0; i < observerCount; i++){ | |
this.observers.get(i).update( context ); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var vehiclePrototype = { | |
init: function ( carModel ) { | |
this.model = carModel; | |
}, | |
getModel: function () { | |
console.log( "The model of this vehicle is.." + this.model); | |
} | |
}; | |
function vehicle( model ) { | |
function F() {}; | |
F.prototype = vehiclePrototype; | |
var f = new F(); | |
f.init( model ); | |
return f; | |
} | |
var car = vehicle( "Ford Escort" ); | |
car.getModel(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var pubsub = {}; | |
(function(myObject) { | |
// Storage for topics that can be broadcast | |
// or listened to | |
var topics = {}; | |
// A 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 )); | |
// Another simple message handler | |
// A simple message logger that logs any topics and data received through our | |
// subscriber | |
var messageLogger = function ( topics, data ) { | |
console.log( "Logging: " + topics + ": " + data ); | |
}; | |
// Subscribers listen for topics they have subscribed to and | |
// invoke a callback function (e.g messageLogger) once a new | |
// notification is broadcast on that topic | |
var subscription = pubsub.subscribe( "inbox/newMessage", messageLogger ); | |
// Publishers are in charge of publishing topics or notifications of | |
// interest to the application. e.g: | |
pubsub.publish( "inbox/newMessage", "hello world!" ); | |
// or | |
pubsub.publish( "inbox/newMessage", ["test", "a", "b", "c"] ); | |
// or | |
pubsub.publish( "inbox/newMessage", { | |
sender: "[email protected]", | |
body: "Hey again!" | |
}); | |
// We can also unsubscribe if we no longer wish for our subscribers | |
// to be notified | |
pubsub.unsubscribe( subscription ); | |
// Once unsubscribed, this for example won't result in our | |
// messageLogger being executed as the subscriber is | |
// no longer listening | |
pubsub.publish( "inbox/newMessage", "Hello! are you still there?" ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var mySingleton = (function () { | |
// Instance stores a reference to the Singleton | |
var instance; | |
function init() { | |
// Singleton | |
// Private methods and variables | |
function privateMethod(){ | |
console.log( "I am private" ); | |
} | |
var privateVariable = "Im also private"; | |
var privateRandomNumber = Math.random(); | |
return { | |
// Public methods and variables | |
publicMethod: function () { | |
console.log( "The public can see me!" ); | |
}, | |
publicProperty: "I am also public", | |
getRandomNumber: function() { | |
return privateRandomNumber; | |
} | |
}; | |
}; | |
return { | |
// Get the Singleton instance if one exists | |
// or create one if it doesn't | |
getInstance: function () { | |
if ( !instance ) { | |
instance = init(); | |
} | |
return instance; | |
} | |
}; | |
})(); | |
var myBadSingleton = (function () { | |
// Instance stores a reference to the Singleton | |
var instance; | |
function init() { | |
// Singleton | |
var privateRandomNumber = Math.random(); | |
return { | |
getRandomNumber: function() { | |
return privateRandomNumber; | |
} | |
}; | |
}; | |
return { | |
// Always create a new Singleton instance | |
getInstance: function () { | |
instance = init(); | |
return instance; | |
} | |
}; | |
})(); | |
// Usage: | |
var singleA = mySingleton.getInstance(); | |
var singleB = mySingleton.getInstance(); | |
console.log( singleA.getRandomNumber() === singleB.getRandomNumber() ); // true | |
var badSingleA = myBadSingleton.getInstance(); | |
var badSingleB = myBadSingleton.getInstance(); | |
console.log( badSingleA.getRandomNumber() !== badSingleB.getRandomNumber() ); // true | |
// Note: as we are working with random numbers, there is a | |
// mathematical possibility both numbers will be the same, | |
// however unlikely. The above example should otherwise still | |
// be valid. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Person = function( firstName, lastName ){ | |
this.firstName = firstName; | |
this.lastName = lastName; | |
this.gender = "male"; | |
}; | |
// a new instance of Person can then easily be created as follows: | |
var clark = new Person( "Clark", "Kent" ); | |
// Define a subclass constructor for for "Superhero": | |
var Superhero = function( firstName, lastName, powers ){ | |
// Invoke the superclass constructor on the new object | |
// then use .call() to invoke the constructor as a method of | |
// the object to be initialized. | |
Person.call( this, firstName, lastName ); | |
// Finally, store their powers, a new array of traits not found in a normal "Person" | |
this.powers = powers; | |
}; | |
Superhero.prototype = Object.create( Person.prototype ); | |
var superman = new Superhero( "Clark", "Kent", ["flight","heat-vision"] ); | |
console.log( superman ); | |
// Outputs Person attributes as well as powers |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment