Education, Programming, Training Notes

Proxy Pattern

The Proxy pattern uses one object as the interface for another object

  • It sits between users or clients of the object and the object itself
  • client makes request to proxy, proxy makes request to object
  • clients may or may not know if they are using a proxy
  • the proxy controls access to the original object (acts as a guardian)
  • often used for performance reasons
    • if the object needs to make expensive HTTP requests (or others), we make batch requests in the proxy in order to send fewer requests to the object
    • proxy can include cashe to store requests for further use
  • Proxies can also be used to delay the instantiation of a slow or resourse intensive object, when it is better for performance to delay
    • we might need the object at some time
    • this is called a Just-In-Time Proxy, which is what we will be making
    • first time that proxy invokes methods of objects will be slow, but subsequent times will be fast as object has already been initialized
    • great thing about this is even if client initializes proxy, we may not need the slow object unless a method on the slowObject is needed

Step 1 – Page: slowObject.js


// JavaScript Document
define(function () {
		'use strict';
		
		var SlowObject = function () { //set up slowObject
			this.someMethod = function () {
				console.log('some method on the slow object was invoked');	//use method to log a statement
			};
		};
		
		return {
			init: function () { //add artificial initialization delay with for loop
				for (var x = 0, max = 1000; x < max; x++) { //for loop iterates 1000 times
					console.log('slowness...');
				}
				return new SlowObject();//once loop finishes, returns new instance of slowObject
			}
		};
});

Step 2 - Page: slowObjectProxy.js


// JavaScript Document
define(function (require) {//use require function
		'use strict';
		
		var SlowObjectProxy, slowObjectInstance, //initialize variables
			slowObject = require('proxy/slowObject');
			
		SlowObjectProxy = function () { //set up constructor for proxy object
			this.someMethod = function () { //add method that matches the slowObject method
				var interval; //add the new variable
				
				if (!slowObjectInstance) { //check if the slowObject has been initialized previously
					slowObjectInstance = slowObject.init();	//if return is falsy, we haven't initialized yet, so we use init method to initialize
				} else { //if it has been initialized
					slowObjectInstance.someMethod();	//we invoke the same method on the slowObject
				}
				
				interval = window.setInterval(invokeMethodWhenExists, 100); //set this up to poll the object and wait for initizialization.
				
				function invokeMethodWhenExists() { //the above interval will invoke this method every 100 seconds in order to check if slowObject has been created yet
					if (slowObjectInstance) { //we check the slowObjectIstance variable, and if truthy
						console.log('proxying some method'); //use a log to know the proxy is working as expected
						window.clearInterval(interval); //clear the interval to stop the loop
						
						slowObjectInstance.someMethod(); //then invoke the method on the slow object
					}
				}
			};
		};
		
		return {
			init: function () {
				return new SlowObjectProxy();	
			}
		};
});

Step 3 - Page: init.js


define(function(require) {
	'use strict';

	return {
		init: function() {
			
			var myProxy, //set up variables
				slowObjectProxy = require('proxy/slowObjectProxy');
				
				myProxy = slowObjectProxy.init(); //initialize the slowObject, which delayed by the interval
				myProxy.someMethod();
		}
	};
});

Step 4 - Page: main.js


// JavaScript Document
require (
	['proxy/init'],
	function ( proxy) {
			'use strict';
	
			var examples = {
					
					proxy:proxy
				};
			
			window.runExample = function (example) {
				examples[example].init();
			};
	}
);

Conclusion

The proxy pattern can be used to control access another object, either because it takes a long time to initialize or it is an expensive operation to carry out

  • proxy exposes same interface as the original object and sits between client and object, intercepting requests and handling on behalf of the object.
Education, Programming, Training Notes

Composite Pattern

Used to treat single objects or collections of objects in the same way

Compositions are used to create nested structures of nodes

  • a node may be a single node (leaf) or a container of nodes
  • the ability to iterate through the composite beginning from any node and moving up the tree

What we will be doing:
  • children with no children are leafs
  • children with kids are containers
  • Step 1 – Page: node.js

    
    // JavaScript Document
    define(function () {
    		'use strict';
    		
    		var Person = function (name) { //set up Person object constructor
    			this.name = name; //add name to a property of the object
    			this.children = []; //add children as property and set to empty aray
    			this.parent = null;	//add parent as property as set to null
    		};
    		
    		Person.prototype.addChild = function (child) { //set up method to add children to Person object
    			this.children.push(child);	//push the child arguement into the children array for the object
    			child.parent = this; //create a reciprocal link by setting current person as parent of child passed to the method.  We need this reciprocal link so we can traverse up and down the tree
    		};
    		
    		Person.prototype.traverseUp = function () { //set up method to traverse up
    			if (this.parent) { //check whether current object has parent
    				console.log(this.name + ' is the child of ' + this.parent.name); //if it does, log out a message
    				this.parent.traverseUp(); //then invoke traverseUp method of parent
    			} else { // if there are no parents
    				console.log(this.name + ' is the root node'); //we then know this is a root node
    			}
    		};
    		
    		Person.prototype.traverseDown = function () { //set up traverseDown
    			if (this.children.length) { //check for children
    				this.children.forEach(function (child) { //if so, iterate through children collection
    							console.log(this.name + ' is the parent of ' + child.name); //send out log statement
    							child.traverseDown(); //then invoke traverseDown on child
    				}, this);//set the context for the forEach method, so inside the handler, this still refers to current person objects
    			} else { //if no children
    				console.log(this.name + ' is a leaf node');	//then object is a leaf node
    			}
    		};
    		return Person; //return the person constructor
    });
    

    Step 2 – Page: init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			
    			var Node = require('composite/node'), //require in node.js
    				root = new Node('Fred'), //set up nodes, al nodes are created in same way
    				child1 = new Node('John'),
    				child2 = new Node('Jane'),
    				child3 = new Node('Jack'),
    				child4 = new Node('Jill'),
    				child5 = new Node('James'),
    				child6 = new Node('Jess')
    				
    				root.addChild(child1); //add two children to root node, then leave child1 as leaf
    				root.addChild(child2);
    				
    				child2.addChild(child3); //add child nodes to child2, making it a container
    				child2.addChild(child4);
    				
    				child4.addChild(child5); //leave child3 as leaf, and make child4 a container with one child
    				
    				child5.addChild(child6); //child5 is container, and child6 is lowest leaf on the tree
    				
    				root.traverseDown(); //displays entire tree
    				root.traverseUp(); //root is the top level, so returns that root is a root node
    				
    				child6.traverseUp(); //displays entire tree
    				child6.traverseDown(); //bottom level, so returns that Jess is a leaf node with no children
    		}
    	};
    });
    

    Step 3 – Page: main.js

    
    // JavaScript Document
    require (
    	['composite/init'],
    	function (composite) {
    			'use strict';
    	
    			var examples = {
    					
    					composite: composite
    					
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Conclusion

    Main purpose of composite pattern is to allow single objects or collections of objects to be used in the same way

    • we don’t need to know if object is container or leaf, we can process it the same way.
    Education, Programming, Training Notes

    Adapter Pattern

    • Used to convert one interface to another
    • an objects interface is the method and properties exposed by the object, what we use to interact with the object
    • useful pattern when something changes and we don’t want to go throughout code and refactor the object
      • It’s not necessary to use this pattern if the object you are changing doesn’t have a lot of dependencies

    Step 1 – Page: oldInterface.js

    
    // This will be a email validation script that will check to see if the string has an at symbol
    define(function () {
    		'use strict';
    		
    		var OldInterface = function () { }; //set up an object constructor
    		
    		OldInterface.prototype.doSomethingOld = function () { //add a method to the constructor prototype
    			console.log('doing the old thing');
    		};
    		
    		return new OldInterface(); //return a new instance of the object
    });
    

    Step 2 – Page: newInterface.js

    
    // This will be a email validation script that will check to see if the string has an at symbol
    define(function () {
    		'use strict';
    		
    		var NewInterface = function () { }; //set up an object constructor
    		
    		NewInterface.prototype.doSomethingNew = function (newArg) { //add a method to the constructor prototype
    			console.log('doing the ', newArg);
    		};
    		
    		return new NewInterface(); //return a new instance of the object
    });
    

    Step 3 – Page: adapter.js

    
    // This will be a email validation script that will check to see if the string has an at symbol
    define(function (require) {
    		'use strict';
    		
    		var newInterface = require('adapter/newInterface'); //require in the new interface
    		
    		return {
    			doSomethingOld: function () { //reset the method from the oldInterface with the method from the new interface
    				return newInterface.doSomethingNew('new thing');	
    			}
    		};
    });
    

    Step 4 – Page: init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			
    			var OldInterfaceAdapter = require('adapter/adapter'); //set up new variable for OldInterface and rename to OldInterfaceAdapter to make it clear to any subsequent coders that we are using an adapter for the oldInterface
    			
    			OldInterfaceAdapter.doSomethingOld();
    		}
    	};
    });
    

    Step 5 – Page: main.js

    
    // JavaScript Document
    require (
    	['adapter/init'],
    	function (adapter) {
    			'use strict';
    	
    			var examples = {
    					
    					adapter:adapter
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Conclusion

    The Adapter pattern allows us to change one part of our application without changing the others. It is also a good example of a design pattern you wouldn’t use when developing your application. Adapters are only needed when there is a change between dependencies, so this pattern only arises when issues occur.

    • it is common to use design patterns when refactoring code to make things work better and more efficiently
    Education, Programming, Training Notes

    Facade Pattern

    The facade is a simple interface that is shown to the public to hide the complexity of the underlying system

    • they conceal the implementation
    • It is a structural pattern that simplifies the use of your API
    • It also shields developers from being locked to an architecture (can change the internals while keeping the look the same to the public)
    • It has been used for a long time in JavaScript, ever since frameworks wrapped a simple interface around the disparate browser API’s

    Step 1 – Page: processor.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	return { //module returns an API of 5 methods that each deal with a different data type.  This is just for example, the processing isn't complex or necessarily useful.  Module doesn't depend on facade, just exposes the API methods.  It could have dependencies with other modules, but should never depend on facade.  Facade depends on this.
    		processString: function (string) { 
    			return string.substring(0, string.length / 2);
    		},
    		processNumber: function (number) {
    			return number * number;
    		},
    		processBoolean: function (bool) {
    			return !bool;
    		},
    		processArray: function (array) {
    			return array.length;
    		},
    		processObject: function (object) {
    			return Object.keys(object).length;	
    		}
    	};
    });
    

    Step 2 – Page: facade.js

    
    // JavaScript Document
    define(function(require) { //must use require function to load the processor module
    	'use strict';
    	
    	var processor = require('facade/processor'); //load the processor as a dependency
    	
    	return { //return the single method contained by the facade
    		processData: function (data) { //this is the method exposed by the facade
    			switch (Object.prototype.toString.call(data)) { //in this method, we use a switch statement to invoke a processor method depending on the data type passed to the facade.  Value that we switch upon is the data type.  We use object.prototype.toString.call method to convert data type to object String, object Number, object Boolean, etc.  We then switch on this
    				case '[object String]':
    					return processor.processString(data);
    					break;
    				case '[object Number]':
    					return processor.processNumber(data);
    					break;	
    				case '[object Boolean]':
    					return processor.processBoolean(data);
    					break;
    				case '[object Array]':
    					return processor.processArray(data);
    					break;
    				case '[object Object]':
    					return processor.processObject(data);
    					break;
    				default:
    					return 'Unable to process the data';
    			}
    		}
    	};
    });
    

    Step 3 – init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			var facade = require('facade/facade'); //add the facade as a dependency
    			
    			console.log(facade.processData('test string')); //log out a bunch of statements
    			console.log(facade.processData(5));
    			console.log(facade.processData(false));
    			console.log(facade.processData([1, 2, 3]));
    			console.log(facade.processData({prop: 'something', other: 'else'}));
    		} //this init file is nicely decoupled from processor.  Processor can be refactored as needed, as long as API methods are the same
    	};
    });
    

    Step 4 – main.js

    
    // JavaScript Document
    require (
    	['facade/init'],
    	function ( facade) {
    			'use strict';
    	
    			var examples = {
    					
    					facade: facade
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Conclusion

    With a facade, we can hide the complexity of the underlying system and just expose a way to interact with the system. It presents a simplified API as the means of working with the application. The subsystems (or modules like the processor) can be changed or refactored as necessary, as long as the API methods remain the same.

    Education, Programming, Training Notes, Web Design

    Speech Synthesis API

    Here is a brand new addition to browser API’s, the Speech Synthesis API.  It is used to make the browser read text out loud to the viewer, and can be implemented for many different effects.  Want a congratulations to be sent to the visitor?  Now you aren’t constrained to simple visual input.  I’ll be extending this with the web audio API in the future, but I wanted to share this new discovery with you today.  Here is how to set things up.

    var utterance  = new SpeechSynthesisUtterance();

    That line will initialize the Speech Synthesis object in the browser, now we need to tell it what to say:

    utterance.text = 'I may be a computer, but I want to be a real boy!';

    That line places a string property for the utterance variable with the supplied text. Now we just need to string the pieces together:

    speechSynthesis.speak(utterance);

    That line will invoke the Speech Synthesis object and pass it the utterance variable, which we set with a text property that will now be read by the browser! Toss those three lines into your browser console right now to see them in action!

    Pretty cool, huh! Now extend your knowledge with the Browser Speech Tutorial from Envato Tuts+, one of my favorite places to go to keep learning about emerging technologies.  Thanks for stopping by!

    Education, Programming, Training Notes

    Iterator Pattern

    Javascript itself has iteration built into the language

    • there are a number of for and forEach methods to iterate through arrays
    • we have the forIn loop to iterate through objects

    Iterator pattern is different as it doesn’t run in a synchronous loop and the iterator keeps track of which items have been processed

    • we manually choose when to extract the data of the next item
    • the purpose is to provide access to the items in a collection contiguously, while keeping track of which items have been accessed
    • common to have a next() method which returns next item in collection
    • some libraries have hasNext, isDone, first, and reset()
    • in JS ES7, iterators will be added as a core part of the language, we have to create our own for the time being, look here for more info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

    Step 1 – Page: iterator.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	var Iterator = function(collection) { //define object constructor, which is passed a collection of items
    		this.collection = collection; //store this collection as a property of the object
    		this.index = 0; //set up an index property to keep track of which items have been processed.  Initialized to 0
    	};
    	
    	Iterator.prototype = {
    		constructor: Iterator, //first thing we need to do is set constructor property for the prototype object to the constructor we created.  If we don't do this, the constructor will point to the object constructor instead.
    		next: function () {
    			return this.collection[this.index++]; //this is the next method, which is a critical component of an iterator.  We are simply returning the next item in the collection with the index property, then we are incrementing it by 1
    		},
    		isDone: function () {
    			return this.index === this.collection.length; //set up isDone method that returns true once all the items in the collection have been iterated through.  We are returning whether the index equals the length of the collection (# of items in the array)
    		},
    		reset: function () { //set up reset method to set the index back to 0, in case we want to iterate again
    			this.index = 0;
    			return this; //then return the iterator so that other methods can be chained on after the reset
    		},
    		take: function (numberOfItems) { //the take method will return a specified number of items and update the index accordingly.  It will receive the number of items we want to take as an argument
    			var newIndex = this.index + numberOfItems, //calculates what the new index will be by adding numberOfItems to the current index and stores this in a variable
    				newArr = Array.prototype.slice.call(this.collection, this.index, newIndex); //we then create a new array using the slice method.  Pass the collection to the call method to as the first argument to set the collection as the this object.  We then pass in the current index as the index to start slicing from. The newIndex is the set as the second argument
    				
    			this.index = newIndex; //set iterators index to the new index
    			return newArr;	//return the new array
    		}
    	};
    	
    	return { //return an object from the module that has one build method.  This is an implementation of the factory pattern
    		build: function (collection) { //build method is passed the collection.  We only need this if object is passed to iterator, in which case we have to build an array for us to work with the data.
    			var keys = Object.keys(collection), //keys method of object constructor will create an array of all the keys in the object.
    				tempArray = [],
    				prop;	
    				
    			if (typeof collection === 'number') { //if a number is passed into the iterator
    				collection = collection.toString();	//convert the number to a string and the iterator can work with it
    			}
    			
    			if (keys.length) { //if object is passed, it is a collection of key value pairs that can be parsed
    				for (prop in collection) { //extract the values from the object
    					tempArray.push(collection[prop]);	//construct a new array from these values
    				}
    				collection = tempArray;//send these values to the iterator
    			}
    			
    			if (collection.length) { //if the collection exists
    				return new Iterator(collection); //initialize the iterator
    			} else {
    				throw ('Iterator cannot be built from Boolean, null, or undefined data');	
    			}
    		}
    	};
    });
    

    Step 2 – Page: init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			var iterator = require('iterator/iterator'), //load the iterator
    				testArray = [{ something: 'yay', other: 123}, {something: 'test', other: 456}], //create a test array
    				myArrayIterator = iterator.build(testArray), //build the array into the iterator, where we can then iterate through data
    				testString = 'teststring', //set up test string
    				myStringIterator = iterator.build(testString); //send testString to iterator
    				
    			console.log(myArrayIterator.next()); //log the data from the first index in the array
    			console.log(myArrayIterator.next()); //log the data from the next index
    			
    			while (!myStringIterator.isDone()) { //loop through test string
    				console.log(myStringIterator.next());	//log the next data in the testString loop
    			}
    			
    			console.log(myStringIterator.reset().take(4).join('')); //we can reset the iterator, then use the take method to choose single values from the array (this will grab the first 4).  We then join the data to create a word.
    		}
    	};
    });
    

    Step 3 – main.js

    
    // JavaScript Document
    require (
    	['iterator/init'],
    	function (iterator) {
    			'use strict';
    	
    			var examples = {
    					iterator: iterator
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Conclusion

    Iterator pattern isn’t as common is JavaScript, but it will soon become a core component of the specification. It decouples the processing of a collection of items, from the collection itself

    • we don’t need to know what the data is or what type, the iterator is designed to control for all events.
    Education, Programming, Training Notes

    Mediator Pattern

    Situation: If you have multiple independent modules that work in a system (parts of a web page or a user interface system) and they must be kept seperate from eachother and aren’t allowed to communicate directly

    Solution: Install a mediator and modules can communicate through mediator, which handles requests and directs the requests to the appropriate module

    • modules that need to communicate are known as colleagues

    Step 1 – Page: colleague.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	var Colleague = function (id, mediator) { // In this step, we will set up colleage constructor.  It accepts arguments of id and an instance of the mediator.  They are set as properties of the colleage instance, below...
    		this.id = id;
    		this.mediator = mediator;
    	};
    	
    	Colleague.prototype.receiveMessage = function (message) { //now we extend the Colleage constructor with a method to receive messages
    		console.log('Module', this.id, 'received message:', message); //receives the message as an argument and logs it to the console
    		return true; //return true once the logging has occurred
    	};
    	
    	Colleague.prototype.sendMessage = function (message, recipientId) { //extend class with method to send mesage, accepts the message and a recipient ID
    		(recipientId) ? this.mediator.send(recipientId, message) : //if you are given a recipientID, then use the mediator send method to send the message to the prescribed colleague.  If recipientID is not supplied...
    			this.mediator.broadcast(message, this); //use the mediator broadcast method to send the message to all colleagues.  We also pass the current id to the broadcast as to prevent the broadcast from sending the message to the colleague that sent it.
    	};
    	
    	return {//rather than return the constructor like we usually do, we will be returning an object with a create method.  
    		create: function (id, mediator) {
    				var that = new Colleague (id, mediator); //Inside this method, we will initialize a new colleage and register it with mediator before passing back the new colleage
    				
    				mediator.register(that);
    				
    				return that;
    		}
    	};
    });
    

    Step 2 – Page: mediator.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	var Mediator = function () { //set up mediator constructor
    		this.colleagues = [];	//this will need to store all colleagues that it will be mediating for.  We don't know them all right now, so set this up as empty array
    	};
    	
    	Mediator.prototype.register = function (colleague) { //this method will register a colleague with the mediator
    		this.colleagues.push(colleague); //by pushing the current collegue into the colleagues array
    	};
    	
    	Mediator.prototype.send = function (recipientId, message) { //this sets up the send method, which sends messages to individual colleagues.  Pass in recipiendId and message
    		this.colleagues.some(function(colleague) { //now we iterate through some of the ids in the collegue array.  Some method works similiarly to forEach method in that it invokes a callback on items in an array.  It will keep invoking callback until return is true, then it stops.
    			if (colleague.id === recipientId) { //this works because send method is only trying to send the message to the intended recipient, so once it finds it's destination, we don't have to keep parsing through the array
    				return colleague.receiveMessage(message);	//it then returns the value from the receiveMessage method on the colleague, which will return true once we are one the target recipient
    			}
    		});
    	};
    	
    	Mediator.prototype.broadcast = function (message, sender) { //sets up broadcast method, receive message to send
    		this.colleagues.forEach(function(colleague) { //uses foreach method to iterate through entire array and run callback function
    			if (colleague.id !== sender.id) { //the function sends the message to all colleagues except the colleague with a matching sender.id
    				colleague.receiveMessage(message);	
    			}
    		});
    	};
    	
    	return Mediator; //return constructor
    });
    

    Step 3 – Page: init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			var mediator, colleague1, colleague2, colleague3, //set up variables
    				Mediator = require('mediator/mediator'), //set up object constructors
    				colleague = require('mediator/colleague');
    				
    			mediator = new Mediator(); //create new instance of object
    			colleague1 = colleague.create('colleague1', mediator); //create colleagues
    			colleague2 = colleague.create('colleague2', mediator);
    			colleague3 = colleague.create('colleague3', mediator);
    			
    			colleague1.sendMessage('Hey there', 'colleague2'); //send message from colleague 1 to 2
    			colleague2.sendMessage('Hi colleague1', 'colleague1');
    			colleague3.sendMessage('Hey guys!'); //broadcast a message with no recipient
    		}
    	};
    });
    

    Step 4 – Page: main.js

    
    // JavaScript Document
    require (
    	['factory/init', 'pubSub/init', 'strategy/init', 'observer/init', 'COR/init', 'mediator/init'],
    	function (factory, pubSub, strategy, observer, COR, mediator) {
    			'use strict';
    	
    			var examples = {
    					factory: factory,
    					pubSub: pubSub,
    					strategy: strategy,
    					observer: observer,
    					COR: COR,
    					mediator: mediator
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Mediator Pattern is great for decoupling a group of modules that need to work together, but don’t need to know about eachother. Instead of every module depending on every other module, creating a tangled mess of dependencies, we can have them interact through the mediator.

    Programming, Training Notes

    Chain of Responsibility Pattern

    Features a request sender and one or more request handlers that form a chain

    • the request sender passes the request to the first handler in the chain
    • the handler then acts on the request, or passes the request to the next handler in the event that it cannot
      • this process is repeated until the request is acted upon or it reaches the end of the chain
      • another variation is for all handlers to handle the request at the exact same time
    • the purpose of this pattern is to decouple the request sender from the request handler
    • it is not a common design pattern implemented in JavaScript, but is a good exercise in object oriented programming in JS

    We will be creating a request sender that is a message (text, email, etc.) and request handlers that can interperet each type of message

    Step 1: Page: handler.js

    
    // JavaScript Document - This will be the base class for the individual handlers
    define(function() {
    	'use strict';
    	
    	var CommunicationHandler = function (communicationType, handler, nextHandler) { //this constructor will accept potentially three arguments.  First two are required and are type of communication and the actual handler to process the communication.  The next argument is the next handler in the chain, if there is one.  These are set as properties of the handler object:
    	
    		this.communicationType = communicationType;
    		this.handler = handler;
    		this.nextHandler = nextHandler;
    		
    	};
    	
    	CommunicationHandler.prototype.handleCommunication = function (communication) { //add a handle request method to prototype for all handlers to inherit
    		if (communication.type !== this.communicationType) { //this checks whether communcation type of the request is equal to the communication type for the handler, so the handler knows whether it can process the request or not
    			(this.nextHandler) ? this.nextHandler.handleCommunication(communication) : //if the handler can't process the communication type, we must check if there is a next handler to pass the request to.  We us a JS terniary operator to see if this.nextHandler is falsy.  If not, we invoke the handle communication method of next handler and pass it the communication.  If so (which means there is no nextHandler specified), return the log statement below
    				console.log('Communication type', communication.type, 'could not be handled');
    			return;
    		}
    		this.handler(communication); //if the handler can handle communcation type, pass the communcation to the handler.
    	};
    	
    	return CommunicationHandler;
    });
    

    Step 2 – Page: email.js

    
    // JavaScript Document -
    define(function(require) { 
    	'use strict';
    	
    	var Handler = require('COR/handler'), //use require function to load the base handler
    		emailHandler;
    		
    	emailHandler = new Handler('email', handleEmail, null); //create email handler by created new instance of base handler class.  Has a type of email, and the handler will be a function called handleEmail.  This will be last stop in the chain, so the nextHandler is set to null
    	
    	function handleEmail(email) { //now define handleEmail function as simple console log statement
    		console.log('Email sent to', email.recipient, 'message: ', email.message);	
    	}
    	
    	return emailHandler; //return instance of emailHandler, not the constructor
    });
    

    Step 3 – Page: text.js

    
    // JavaScript Document -
    define(function(require) { 
    	'use strict';
    	
    	var Handler = require('COR/handler'), //use require function to load the base handler
    		emailHandler = require('COR/handlers/email'), //also load in the email handler, that is the next step in the chain from this.
    		smsHandler;
    		
    	smsHandler = new Handler('sms', handleSMS, emailHandler); //set up the handler, takes sms data type, passes to handleSMS function, with emailHandler the next stop in the chain
    	
    	function handleSMS(sms) { //set up the function to receive the message and log it to the console
    		console.log('SMS sent to number', sms.number, 'message: ', sms.message);	
    	}
    	
    	return smsHandler; //return the instance
    });
    

    Step 4 – Page: call.js

    
    // JavaScript Document -
    define(function(require) { 
    	'use strict';
    	
    	var Handler = require('COR/handler'), //use require function to load the base handler
    		smsHandler = require('COR/handlers/text'), //load text handler as it is the next step in the chain
    		callHandler;
    		
    	callHandler = new Handler('call', handleCall, smsHandler); //set up the handler, takes call as data type, passes to handleCall function, with smsHandler as the next stop in the chain
    	
    	function handleCall(call) { //set up the function to receive the message and log it to the console
    		console.log('Call placed to number', call.number, 'from number ', call.ownNumber);	
    	}
    	
    	return callHandler; //return the instance
    });
    

    Step 5 – Page: init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			
    			var call, sms, email, handler, telepathy, //create communication object variables
    				Handler = require('COR/handler'), //capitalize the constructor
    				callHandler = require('COR/handlers/call'); //we load the first handler in the chain, the call handler.  In real world application, first handler will always be the most common communication type
    				
    			call = {
    				type: 'call',
    				number: '0123456789',
    				ownNumber: '987654321'
    			}; //set up a call
    			
    			sms = {
    				type: 'sms',
    				number: '02468357',
    				message: 'Hey Guy'	
    			}; //set up a text message
    			
    			email = {
    				type: 'email',
    				recipient: 'james@jamesportis.com',
    				message: 'Hey Guy'	
    			}; //set up an email
    			
    			telepathy = {
    				type: 'esp',
    				target: 'Anyone in the world',
    				message: 'I am in your head'	
    			}; //this will not display at all is there is no handler for this data type
    			
    			handler = new Handler(null, null, callHandler); //to set up an empty handler, create instance of handler with no type and no handler, then start the chain by passing it the first step, or the call handler
    			handler.handleCommunication(email); //now start the process using handlers handleRequest method.
    			handler.handleCommunication(sms);
    			handler.handleCommunication(call);
    			handler.handleCommunication(telepathy);
    		}
    	};
    });
    

    Step 6 – Page: main.js

    
    // JavaScript Document
    require (
    	['COR/init'],
    	function (COR) {
    			'use strict';
    	
    			var examples = {
    					COR: COR
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Each handler is only processing one type of data. This makes it easy to add new handlers, as each handler is only coupled to one other handler (next in chain), and the client is only coupled to first handler.

    This method is useful if we have a variety of unique data types that all have to be handled in individual ways

    • great for loose coupling
    • makes extending the system very easy
    Programming, Training Notes

    Factory Pattern

    The factory pattern consists of a collection of objects, a factory, and a client that requires instances of the objects. The client controls the process, but is decoupled from the actual construction of the objects. Makes it easy to extend new types of objects

    Step 1: Page – mediaFactory.js

    
    // The factory pattern consists of a collection of objects, a factory, and a client that requires instances of the objects.  The client controls the process, but is decoupled from the actual construction of the objects.  Makes it easy to extend new types of objects
    define(function (require) {
    	'use strict';
    	
    	var media = {
    		Video: require('factory/video'),
    		Image: require('factory/image')	
    	};
    	
    	return {
    		createMedia: function (type, attributes) {
    			var MediaType = media[type];
    			
    			return new MediaType(attributes);	
    		}
    	};
    });
    

    Step 2: Page – image.js

    
    // We are working with a factory pattern right now.  Factory patterns are creational patterns that can wrap a constructor so that it returns instances of objects.  It is used often in JS to simplify the creation of complex objects and to create a large number of similar objects
    define(function () {
    	'use strict';
    	
    	var Image = function (attributes) {
    		this.width = attributes.width || 0;
    		this.height = attributes.height || 0;
    		this.name = attributes.name || '';
    	};
    	
    	return Image;
    });
    

    Step 3: Page – video.js

    
    // We are working with a factory pattern right now.  Factory patterns are creational patterns that can wrap a constructor so that it returns instances of objects.  It is used often in JS to simplify the creation of complex objects and to create a large number of similar objects
    define(function () {
    	'use strict';
    	
    	var Video = function (attributes) {
    		this.length = attributes.length || 0;
    		this.name = attributes.name || '';
    	};
    	
    	return Video;
    });
    

    Step 4: Page – main.js

    
    // JavaScript Document
    require (
    	['factory/init', 'pubSub/init', 'strategy/init', 'observer/init'],
    	function (factory) {
    			'use strict';
    	
    			var examples = {
    					factory: factory
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    
    

    Step 4: Page – init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			
    			var myVideo, myImage,
    				mediaFactory = require('factory/mediaFactory');
    				
    				myVideo = mediaFactory.createMedia('Video', {
    					length: 3.5,
    					name: 'My video'
    				});
    				
    				myImage = mediaFactory.createMedia('Image', {
    					width: 100,
    					height: 11,
    					name: 'My Image'
    				});
    				
    				console.log(myVideo);
    				console.log(myImage);
    		}
    	};
    });
    
    Programming, Training Notes

    Observer Pattern

    • closely related to pubsub pattern, in fact, many people think of pubsub as a special use of the observer pattern
    • difference is that pubsub create global message buss for communication between components, while observer is more specific and requires that observes subscibe directly to object being observed
    • this pattern promotes loose coupling between objects, and is very common in javascript

    Initializing the Design Pattern

    • we will need a object called subject, which is the object be observed, and we need an observer
    • subject will maintain list of observes and provides an api to allow for observation and notification of changes
    • observer list is entity in its own right that handles adding and removing observers

    Step 1: Page – observer.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	var Observers = function() { //constructor for the observers object
    		this.observers = []; //we set a single property called observers, and initialize it with an empty array
    	};
    	
    	Observers.prototype.add = function (observer) { //this is the method to add an observer
    		this.observers.push(observer); //receives the observer as an argument, then pushes that observer to the array
    	};
    	
    	Observers.prototype.remove = function (observerToRemove) { //method for removing observer
    		this.observers = this.observers.filter(function(observer) { //javascripts filter array method is used to test each object in array.  Filter method doesn't alter array its called upon, but it does create new array, so the new array is then set to the value of the old array.  The callback function passed to filter method is passed current observer and is invoked for each member of array
    			return observer !== observerToRemove; //this method returns true if item should be included, and false if not.  In this case, when observer mathes observerToRemove, returns false and observerToRemove is not included in returned array.
    		});
    	};
    	
    	Observers.prototype.get = function () { //method to get list of observers
    		return this.observers; //just returns list of observers
    	};
    	
    	return Observers; //then return the constructor
    });
    

    Step 2: Page – subject.js

    
    // JavaScript Document
    define(function(require) {
    	'use strict';
    	
    	var Observers = require('observer/observers'); //use require module to bring in observer.js we just created.  Capitalize the object because it takes in a constructor
    	
    	var Collection = function (items) { //the subject will hold of list of items the observer is subscribed to.  Subject is based on array and observers are notified whenever an item is added or removed from this array
    		this.observers = new Observers(); //subject maintains list of observers
    		this.collection = items || []; //the array being observed is under property called collection, and is initalized as empty array
    	};
    	
    	Collection.prototype.observe = function (observer) { //observe method receive observer to add
    		this.observers.add(observer); //and passes the observer to the array with the add method
    	};
    	
    	Collection.prototype.unObserve = function (observer) {//unObserve method receive observer
    		this.observers.remove(observer);	//and passes data to the remove method to be taken from the array
    	};
    	
    	Collection.prototype.notify = function (event, data) { //this method will notify observer of a change in state.  Receives event and data to pass to observers
    		this.observers.get().forEach(function (observer) { //inside method, must get the list of observers.  Then hook into the array with forEach method and create callback that is passed each observer from array of observers
    			observer.notify(event, data); //inside callback we use notify method and pass through name of event, and the data
    		});
    	};
    	
    	Collection.prototype.add = function (item) { //create subjects add method receive the new item to add to the array
    		this.collection.push(item); //then pushes the new item into the collection array
    		this.notify('added', item); //then invokes notify method and specifies the event name as added, then passes item that was added to collection
    	};
    	
    	Collection.prototype.remove = function (itemToRemove) { //remove method for collection object
    		this.collection = this.collection.filter(function (item) { //receive the item to remove and uses filter method of override collection array
    			if (item !== itemToRemove) { //if the item is not the item to remove, returns true
    				return true;
    			}
    			this.notify('removed', item); //if it is the item to remove, we invoke notify method first and specify the event name as removed, then pass the item for removal
    			return false;
    		}, this);
    	};
    	
    	return Collection; //return the constructor
    });
    

    Step 3: Page – observer.js

    
    // JavaScript Document
    define(function() {
    	'use strict';
    	
    	var Observer = function (name) { //add simple observer class so we can create new observers.  The constructor will accept a name property so we know which observer is which
    		this.name = name;
    	};
    	
    	Observer.prototype.notify = function (event, data) { //observers will need a notify method
    		console.log('The event was ', '"' + event + '",', 'the data was', data, 'and I am ', this.name);//add log statement for example
    	};
    	
    	return Observer;
    });
    

    Step 4: Page – main.js

    
    // JavaScript Document
    require (
    	['factory/init', 'pubSub/init', 'strategy/init', 'observer/init'],
    	function (factory, pubSub, strategy, observer) {
    			'use strict';
    	
    			var examples = {
    					factory: factory,
    					pubSub: pubSub,
    					strategy: strategy,
    					observer: observer
    				};
    			
    			window.runExample = function (example) {
    				examples[example].init();
    			};
    	}
    );
    

    Step 5: Page – init.js

    
    define(function(require) {
    	'use strict';
    
    	return {
    		init: function() {
    			var subject, observer, otherObserver, data, moreData, //add variables
    				Subject = require('observer/subject'), //oad subject module
    				Observer = require('observer/observer'); //load observer module
    				
    			subject = new Subject(); //instantiate a subject
    			observer = new Observer('observer1'); //instantiate observer
    			otherObserver = new Observer('observer2'); //initialize other observer
    			
    			data = { //create data objects to pass into items being observed
    				prop: 'something'
    			};
    			moreData = {
    				prop: 'something else'
    			};
    			
    			subject.observe(observer); //add our observers to observer collection
    			subject.observe(otherObserver);
    			
    			subject.add(data); //add our data to the subjects collection
    			subject.add(moreData);
    			
    			subject.unObserve(observer);
    			
    			subject.remove(data);
    		}
    	};
    });
    

    In this situation, the observers will be coupled to the subjects. This isn’t inherently bad as some coupling is okay, and indeed, data in your applications will often necessarily be coupled. However, we want to avoid any unnecessary, unintentional or excessive coupling

    Education, Programming, Training Notes

    Strategy Pattern

    The strategy pattern is used to allow for a behavior to be selected at code run time.

    • this can be based on input data or other cues
    • The different behaviors are knows as the strategies
    • The strategy pattern is easy to implement in JS, but it’s not as commonly used as some of the other design patterns
    • This pattern is most useful in the situation that you have lots of similiar behaviors or modules doing similiar actions and you can’t code in which behavior will occur when the code runs live

    The strategy module needs to expose a method for the strategy or behavior to be selected. It must also provide a way for the selected strategy (also called concrete strategy) to be invoked or used.

    The beauty of this pattern is that main strategy doesn’t know anything about concrete (sub) strategies, and vice-versa. This makes it easy to add or remove stategies in the future.

    Implementation

    Page: strategy.js


    // JavaScript Document
    define(function () {
    'use strict';

    var Validator = function () {}; //this sets up main validation subroutine. In this example, we are creating a data validation script that will be different depending on what type of data is being validated.

    Validator.prototype.selectValidator = function (validator) { //this allows for the concrete strategies to be selected.

    this.validator = validator; //This will receive the strategies as an argument, and can set the argument as a property of the main validator.

    return this; //return the main validator to enable chaining
    };

    Validator.prototype.validate = function (value) { //simple validate method that invokes the sub-validation strategy of the same name. It receives the value to validate as an argument, so we must make sure a validator has been selected before we attempt to use it. If not, we will throw and error.
    if (this.validator) {
    return this.validator.validate(value);
    }
    throw ('No Validator Selected');

    };

    return Validator; //return the object constructor
    });

    Page: telValidator.js


    // This will be a telephone validation script that will check to see if the numbers entered into a telephone form object are valid
    define(function () {
    'use strict';

    return {
    validate: function (value) { //the validation function receive the data to evaluate as a value
    return (/^[0-9]{10}$/g).test(value);
    }
    };
    });

    Page: emailValidator.js


    // This will be a email validation script that will check to see if the string has an at symbol
    define(function () {
    'use strict';

    return {
    validate: function (value) { //the validation function receive the data to evaluate as a value
    return value.indexOf('@') !== -1; //this line checks if there is an @ symbol in the entered string
    }
    };
    });

    Page: init.js


    define(function(require) {
    'use strict';

    return {
    init: function() {
    var Strategy = require('strategy/strategy'),
    telValidator = require('strategy/telValidator'),
    emailValidator = require('strategy/emailValidator'),
    validator;

    validator = new Strategy(); //create a new validator by invoking strategy constructor

    console.log(validator.selectValidator(telValidator).validate(123456789)); //this is testing the validation strategy for a 9 digit number, which should fail validation

    console.log(validator.selectValidator(emailValidator).validate('jamesAtjamesportis.com'));//testing email varification strategy, no at symbol so this should fail
    }
    };
    });

    Programming, Training Notes, Web Design

    Publisher / Subscriber Pattern

    This Lesson teaches the Publisher / Subscriber pattern, which is used to allow modules to communicate with eachother without hard dependencies. It is a great pattern for decoupling modules in your program

    • It is very common to use this pattern in JS applications
    • this pattern can easily be overused as not all coupling between modules is bad
    • DO NOT use pubSub to the point where no modules depend on eachother in your application, this can be confusing and lead to code bloat

     
    First Step is to set up PubSub module:

    // JavaScript Document - PubSub module will return the methods publish and subscribe and we will need an object to store registered callbacks (subscribers)
    define(function () {
    'use strict';

    var subscribers = {};

    return {
    publish: function (topic, data) {//this function receives the topic to publish, and optionaly some data to pass to the subscribers
    if (!subscribers[topic]) { //check if there are subscribers of the topic. If not, it is not worth publishing (?)
    return;
    }

    subscribers[topic].forEach(function (subscriber) {//now iterate the array for the topic, invoking any subscribers and passing any data supplied to publish method. We use forEach method to iterate array, callback function passed to forEach method is invoked for each callback in the array, which is then invoked and passed the data (?)
    subscriber(data);
    });
    },
    subscribe: function (topic, callback) {//best to work with subscribe function first, this is method that other modules will use to register a callback with. It accepts two arguments, event name to subscribe to (topic) and callback function to invoke when topic us published.
    var index; //add an index variable to subscribe method, this will allow for unsubscriptions
    if (!subscribers[topic]) { //first we must check if the topic being registered already exists. This checks is subscriber.topic is falsey, and if it is, then that topic is created and pushed into an empty array
    subscribers[topic] = []; //if not, it must be created as an array
    }

    index = subscribers[topic].push(callback) -1; //then the callback is pushed into the subscriber array. Also, the return value is then added to the index variable. Since push method returns new length of array, subracting one from it gives us the index of the callback we just added

    return { //now we will return object from subscribe method that exposes the dispose method. It is common to allow subscribers to unsubscribe, and this is how we will do it
    dispose: function() {
    subscribers[topic].splice(index, 1); //in dispose method, we slice our the newest callback from the array of subscribers.
    }
    };
    }
    };
    });

    We will then set up the individual publisher and subscriber modules, called ModuleA and ModuleB for convenience


    // JavaScript Document setting up subscription module
    define(function (require) {
    'use strict';

    var pubSub = require('pubSub/pubSub'), //load pubSub module
    subscription; //add new variable for subscription

    subscription = pubSub.subscribe('atopic', function (data) { //this uses the subscribe method to subscribe to a topic. 2nd level populates the subscription variable with the method that is returned from subscribe method
    console.log('atopic was published with the data: ' + data.something); //inside handler function, log out a message and the data argument
    subscription.dispose(); //inside handler, we invoke this new method.
    });

    });

    and


    // JavaScript Document setting up Publisher Module
    define(function (require) { //use require function
    'use strict';

    var pubSub = require('pubSub/pubSub'); //load pubSub module

    return { //now we want to return a method that lets us publish to topic
    publishEvent: function () {
    var data = { //this creates a simple data object with a single property with...
    something: 'some data' //the key of something and the value of some data
    };

    pubSub.publish('atopic', data); //then pubSub modules publish method is used to publish to topic called atopic and pass through our data object
    }
    };

    });

    We then set up our initialization script


    define(function(require) { //now we must update the init module in our pubSub folder to require the new modules
    'use strict';

    return {
    init: function() {

    var moduleA = require('pubSub/moduleA'),
    moduleB = require('pubSub/moduleB'); //loads the modules

    moduleB.publishEvent();//use publish event method in moduleB to publish the event
    moduleB.publishEvent();

    }
    };
    });

    and then add this initialization to our Main JavaScript file


    // JavaScript Document
    require (
    ['factory/init', 'pubSub/init'],
    function (factory, pubSub) {
    'use strict';

    var examples = {
    factory: factory,
    pubSub: pubSub
    };

    window.runExample = function (example) {
    examples[example].init();
    };
    }
    );

    With all that complete, we connect the main.js file to the bottom of the body in our index.html file so we can see our work live:


    <script data-main="js/main" src="js/main.js">

    Once the page loads, we can open the browser console and use

    runExample('pubSub')

    to see our pubSub module in action!

    Summary

    In this lesson, we looked at pubsub method implementation. Our module exposes two methods, publish method notifies subscribers that something has occured. This occurs over named channel (topic). Subscribe method allows modules to subscribe to notifications (events) and registers a callback that is invoked wwhen event is published. Can easily pass data into callbacks and can supply dispose method that can be used to unsubscribe from events.

    Main advantage of pubSub is that it allows us to keep modules loosely coupled, but it also makes the relationships between the modules obscured, so it can be overused easily and cause confusion.