Dec 04 2008

5

Registry Class for Mootools

I have been building some pretty large apps lately and I found the need for the registry design pattern in some of my javascript. I went with this approach because I wanted to minimize the power my objects had, yet I needed some kind of blackboard where all objects could check and report to.

In addition I found that implementing events onto the class made for a very effective event handler as well.

var Registry = new Class({
 
	Implements : [Events],
 
	conf : {},
 
	set : function(path,value){
		var fragments = path.split('/');
 
		if( fragments.shift() !== '') return false; // remove empty, first component
		if(fragments.length > 0 && fragments[fragments.length - 1] == '') fragments.pop();
 
		var obj = {}; var ref = obj; var len = fragments.length;
		if( len > 0){
			for(i = 0; i < len-1; i++){
				ref[fragments[i]] = {};
				ref = ref[fragments[i]];
			}					
			ref[fragments[len-1]] = value;
			this.conf = $merge(this.conf,obj);
		} else {
			this.conf = value;
		}
	},
 
	get : function(path){
		var fragments = path.split('/');
 
		if( fragments.shift() !== '') return null;
		if(fragments.length > 0 && fragments[fragments.length -1] == '') fragments.pop();
 
		var ref = this.conf; var path_exists = true; var i = 0; var len = fragments.length;
		while(path_exists && i < len){
			path_exists = path_exists && (ref[fragments[i]] !== undefined);
			ref = ref[fragments[i]]; i++;
		}
 
		return ref;
	}
 
});

The class is pretty simple but it provides for a powerful hierarchical syntax. Only two methods are supplied ‘get’ and ’set’.

Example:

var reg = new Registry();
 
reg.set('/Options/Default',{'name' : 'test', 'version' : 1});
 
reg.set('/Options/Default/name', 'changed');
 
reg.set('/dynamically/creates/nested/objects', true);
 
reg.get('/Options/Default');
/* returns
{
 name : 'changed',
 version : 1
}
*/
 
reg.get('/Options/Default/version'); // returns 1
 
reg.get('/');
/* returns
{
 Options : {
	Default : {
		name : 'changed',
		version : 1
	}
 },
 
 dynamically : {
	creates : {
		nested : {
			objects : true
		}
	}
 }
}
*/

I found it extremely useful for configuration objects for classes that were initialized in a tree fashion. It also seemed to help with the readability and organization of code. I also had several places where I had multiple objects doing completely different things to the same Request.JSON result. With this class I just stored it in a single place and fired off my event. I found it extremely useful to use the class as a global event manager for cases such as this. I ended up using a dot notation naming convention for my events which helped greatly in documentation and API design.

reg.addEvent('App.initialize',function(){});
 
reg.addEvent('App.shutdown',function(){});
 
reg.addEvent('Data.feed1.loaded',function(){});
 
reg.fireEvent('App.shutdown');

In my actual production code I had my Registry class implement my Singleton Class Mutator. This way I could initialize the registry object multiple times in my code without the need to worry about scope.

Tags: , , ,