Posts Tagged ‘OOP’

Javascript OOP Design Pattern

Tuesday, April 13th, 2010

A Simple Static Object

// Creating Namespace
var Namespace = {};

// Creating Static Object
Namespace.Model = (function()  {
	// static private methods

	return { // static public methods
		staticMethod: function() {

		}
	};
})();

A Simple Object with Singleton Control

// Creating Namespace
var Namespace = {};

// Creating Object
Namespace.Model = (function()  {
	// static private methods

	function constructor(caller, options) {
		// instance private methods
		var options = $.extend({
			// attributes here
		}, options);

		return { // instance public methods
			initialize: function() {
				// init code here
			}
		};
	} // constructor end

	var uniqueInstance; // private attribute that holds the single instance.
	return { // static public methods
		getInstance: function(caller, options)	{
			if(!uniqueInstance) {
				uniqueInstance = constructor(caller, options);
				uniqueInstance.initialize();
			}
			return uniqueInstance;
		}
	};
})();

// Get Object Instance via jQuery Call
$.fn.method = function(options) {
	var caller = $(this);
	return Namespace.Model.getInstance(caller, options);
}

Create Object with Inheritable

// Creating Abstract Object
var Person = (function()  {
	// static private methods
	var GENDER = {MALE:'male', FEMALE:'female'};

	function constructor() {
		// instance private methods
		var age = 30;
		var gender = GENDER.FEMALE;
		var name = null;

		function shopping() {
			log( 'I like shopping...' );
		}

		return { // instance public methods
			initialize: function() {
				log( 'init Person...' );
			},
			setAge: function(val) {
				age = val;
			},
			getAge: function() {
				return age;
			},
			setGender: function(val) {
				gender = val;
			},
			getGender: function() {
				return gender;
			},
			setName: function(val) {
				name = val;
			},
			getName: function() {
				return name;
			},
			hello: function() {
				log( 'hello...' );
			},
			laugh: function() {
				log( '[Person] hehehe' );
			},
			desc: function() {
				log( 'I am '+age+' years old, a '+gender+' person' );
			},
			toString: function() {
				return 'Person';
			}
		};
	} // constructor end

	return { // static public methods
		GENDER: GENDER,
		getInstance: function()	{
			var instance = constructor();
			instance.initialize();
			return instance;
		},
		constructor: constructor // for inheritable
	};
})();

// Creating Inherit Object (Level 1)
var Male = (function()  {
	// static private methods

	function constructor() {
		// instance private methods
		var _prototype = null; // variable to remember parent object

		return inherit(Person.constructor(), { // instance public methods inherit from Person
			initialize: function() {
				this.prototype.initialize();
				this.setGender(Person.GENDER.MALE);
				log( 'init Male...' );
				_prototype = this.prototype;
			},
			play: function() {
				log( '[Male] I like play...' );
			},
			laugh: function() {
				_prototype.laugh(); // call parent's method
				log( '[Male] haha' );
			},
			toString: function() {
				return 'Male';
			}
		});
	} // constructor end

	return { // static public methods
		getInstance: function()	{
			var instance = constructor();
			instance.initialize();
			return instance;
		},
		constructor: constructor // for inheritable
	};
})();

// Creating Inherit Object (Level 2)
var Boy = (function()  {
	// static private methods

	function constructor() {
		// instance private methods
		var _prototype = null; // variable to remember parent object

		return inherit(Male.constructor(), { // instance public methods inherit from Male
			initialize: function() {
				this.prototype.initialize();
				this.setAge(16);
				log( 'init Boy...' );
				_prototype = this.prototype;
			},
			hi: function() {
				log( 'What\'s up?' );
			},
			laugh: function() {
				_prototype.laugh(); // call parent's method
				log( '[Boy] Wahahahahahaha' );
			},
			toString: function() {
				return 'Boy';
			}
		});
	} // constructor end

	return { // static public methods
		getInstance: function()	{
			var instance = constructor();
			instance.initialize();
			return instance;
		},
		constructor: constructor // for inheritable
	};
})();

// Creating Inherit Object (Level 3)
var David = (function()  {
	// static private methods

	function constructor() {
		// instance private methods
		var _prototype = null; // variable to remember parent object

		return inherit(Boy.constructor(), { // instance public methods inherit from Boy
			initialize: function() {
				this.prototype.initialize();
				this.setName('David');
				log( 'init David...' );
				_prototype = this.prototype;
			},
			laugh: function() {
				_prototype.laugh(); // call parent's method
				log( '[David] lol' );
			},
			toString: function() {
				return 'David';
			}
		});
	} // constructor end

	return { // static public methods
		getInstance: function()	{
			var instance = constructor();
			instance.initialize();
			return instance;
		},
		constructor: constructor // for inheritable
	};
})();

// method to do object inherit routine
function inherit(parent, child) {
	var target = parent;
	// hook target object's 'prototype' property as current parent
	target.prototype = {
		prototype: parent.prototype,
		child: target
	};
	// re-assign parent's parent's child property
	if( target.prototype.prototype ) {
		target.prototype.prototype.child = target.prototype;
	} else { // if parent's parent doesn't exist, then delete it
		delete target.prototype.prototype;
	}
	// re-construct target's parent object properties
	for (var property in parent) {
		if( property != 'prototype' && property != 'child' ) {
			target.prototype[property] = parent[property];
		}
	}
	// re-construct target object properties
	for (var property in child) {
		if( property != 'prototype' && property != 'child' ) {
			target[property] = child[property];
		}
	}
	return target;
}

// method to show log on console
function log(msg) {
	if( window.console != null ) {
		console.log(msg);
	}
}

Example Code

log( '========== [create Person instance] ===========' );
var person = Person.getInstance();
person.hello();
person.laugh();
person.desc();
log( '========== [create David instance] ===========' );
var david = David.getInstance();
david.hello();
david.hi();
david.laugh();
david.desc();
david.shopping(); // will occur error, because it won't inherit private methods

Example Code Output Result:

Reference:
http://msdn.microsoft.com/zh-tw/magazine/cc163419.aspx(中文)
http://msdn.microsoft.com/en/magazine/cc163419.aspx
Pro Javascript Design Patterns