Skip to content

Instantly share code, notes, and snippets.

@psyked
Last active November 13, 2018 15:35
Show Gist options
  • Save psyked/5847065 to your computer and use it in GitHub Desktop.
Save psyked/5847065 to your computer and use it in GitHub Desktop.
JavaScript Observer Pattern - Module Pattern implementation
var Observable = (function()
{
"use strict";
/**
* @constructor
* @returns {{attach: Function, detach: Function, notify: Function}}
*/
var constructor = function()
{
/**
* @private
* @type {Array}
*/
var observers = [];
/**
* @param observer {Observable}
* @param event {string}
*/
function attach(observer, event)
{
observers.push({
observer : observer,
event : event
});
}
/**
* @param observer {Observable}
*/
function detach(observer)
{
for(var i = 0, l = observers.length; i < l; i++)
{
if(observers[i].observer === observer)
{
observers.splice(i, 1);
i--;
}
}
}
/**
* @param event {string}
* @param data {object}
*/
function notify(event, data)
{
var item;
for(var key in observers)
{
item = observers[key];
if(!(item.event !== undefined && item.event !== event))
{
item.observer.notify(event, data);
}
}
}
return {
attach : attach,
detach : detach,
notify : notify
}
}
return constructor;
})();
var Users = (function()
{
"use strict";
/**
* @constructor
* @returns {{addUser: Function, removeUser: Function}}
*/
var constructor = function()
{
/**
* @private
* @type {object}
*/
var users = {};
/**
* @param username {string}
* @param email {string}
* @param address {string}
* @param postcode {string}
*/
function addUser(username, email, address, postcode)
{
users[username] = {
username : username,
email : email,
address : address,
postcode : postcode
}
this.notify(constructor.ADD_USER, users[username]);
}
/**
* @param username {string}
*/
function removeUser(username)
{
if(users[username] !== undefined)
{
this.notify(constructor.REMOVE_USER, users[username]);
users[username] = undefined;
}
else
{
this.notify(constructor.ERROR, 'Removing user failed, username not found ' + username);
}
}
var instance = new Observable();
instance.addUser = addUser;
instance.removeUser = removeUser;
return instance;
}
constructor.ADD_USER = "addUser";
constructor.REMOVE_USER = "removeUser";
constructor.ERROR = "errorUser";
return constructor;
})();
var SendEmailToNewUsers = (function()
{
"use strict";
/**
* @constructor
* @returns {Observable}
*/
var constructor = function()
{
/**
* @param event {string}
* @param data {object}
*/
function handleNotify(event, data)
{
if (event === Users.ADD_USER)
{
document.write('\n[sendmail] Added a user, sending email to ' + data['email']);
}
else if (event === Users.REMOVE_USER)
{
document.write('\n[sendmail] Removed a user, sending email to ' + data['email']);
}
}
var instance = new Observable();
instance.notify = handleNotify;
return instance;
}
return constructor;
})();
var WelcomeNewUser = (function()
{
"use strict";
/**
* @constructor
* @returns {Observable}
*/
var constructor = function()
{
/**
* @param event {string}
* @param data {object}
*/
function handleNotify(event, data)
{
document.write('\n[welcome] Welcome aboard, ' + data['username']);
}
var instance = new Observable();
instance.notify = handleNotify;
return instance;
}
return constructor;
})();
var ErrorUser = (function()
{
"use strict";
/**
* @constructor
* @returns {Observable}
*/
var constructor = function()
{
/**
* @param event {string}
* @param data {object}
*/
function handleNotify(event, data)
{
document.write('\n[error] There was an error: ' + data);
}
var instance = new Observable();
instance.notify = handleNotify;
return instance;
}
return constructor;
})();
/**
* Main code
*/
document.write('\n<pre>');
document.write('\nStarting test');
// Observable
var users = new Users();
// Observers
users.attach(new SendEmailToNewUsers());
users.attach(new WelcomeNewUser(), Users.ADD_USER);
users.attach(new ErrorUser(), Users.ERROR);
// Process users
users.addUser('Ian Ross', '[email protected]', '66 London Street', 'PE1 2RF');
users.addUser('Mike Smith', '[email protected]', '123 Main Road', 'PE2 6FX');
users.removeUser('Ian Ross');
users.addUser('John Wayne', '[email protected]', '999 Kansas Road', 'LE5 5AZ');
users.removeUser('Anthony McQuinn');
users.removeUser('John Wayne');
document.write('\nEnded test');
document.write('\n</pre>');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment