开发者

Is this a good decorator pattern for javascript?

I need some simple objects that could become more complex later, with many different properties, so i thought to decorator pattern. I made this looking at Crockford's power constructor and object augmentation:

//add property to object
Object.prototype.addProperty = function(name, func){
    for(propertyName in this){
        if(propertyName == name){
            throw new Error(propertyName + " is already defined");
        }
    }
    this[name] = func;
};

//constructor of base object
var BasicConstructor = function(param){

    var _privateVar = param;
    return{
        getPrivateVar: function(){
            return _privateVar;
        }
    };
};

//a simple decorator, adds one private attribute and one privileged method 
var simpleDecorator = function(obj, param){

    var _privateVar = param;

    var privilegedMethod1 = function(){
        return "privateVar of decorator is: " + _privateVar;
    };

    obj.addProperty("privilegedMethod1", privilegedMethod1);

    return obj;
}

//a more complex decorator, adds public and private properties
var complexDecorator = function(obj, param1, param2){

    //private properties
    var _privateVar = param1;
    var _privateMethod = function(x){
        for(var i=0; i<x; i++){
            _privateVar += x;
        }
        return _privateVar;
    };

    //public properties
    var publicVar = "I'm public";
    obj.addProperty("publicVar", publicVar);

    var privilegedMethod2 = function(){
        return _privateMethod(param2); 
    };
    obj.addProperty("privilegedMethod2", privilegedMethod2);

    var publicMethod = function(){
        var temp = this.privilegedMethod2();
        return "do something: " + temp + " - publicVar is: " + this.publicVar;
    };
    obj.addProperty("publicMethod", publicMethod);

    return obj;
}

//new basic object
var myObj = new BasicConstructor("obj1");

//the basic object will be decorat开发者_JAVA技巧ed
var myObj = simpleDecorator(obj, "aParam");

//the basic object will be decorated with other properties
var myObj = complexDecorator(obj, 2, 3);

Is this a good way to have Decorator Pattern in javascript? Are there other better ways to do this?


There are various implementations of the Decorator pattern in Javascript on Wikipedia and other sites - (1), (2), (3). The pattern is defined as:

the decorator pattern is a design pattern that allows new/additional behaviour to be added to an existing object dynamically.

Object extension is already build into the language itself. Objects can be easily extended, and properties can be added anytime. So why should you have to jump through hoops to achieve this? Shouldn't something like this suffice:

var person = { name: "Jack Bauer" };

// Decorated the object with ability to say a given phrase
person.say = function(phrase) {
    alert(phrase);
}

// Using the decorated functionality
person.say("Damn it!");

If you want a method to apply to all objects that were created using this function, then add that method/properties to the function's prototype.

Update: If you have clearly defined pieces of functionality which can be mixed and matched as needed into certain types of objects, then the MooTools approach of extending and mixing in behavior into objects is nicely done. To give an example, consider a UI component that can be resized, dragged around with a handle, and deleted by clicking a tick mark at the top-right corner. You may not want to create each component with these behaviors but define all these behaviors separately each into their own object. And later mix in these behaviors into each type of component as needed.

var Resizable = {
   ...
};

var Draggable = {
   ...
};

var Deletable = {
   ...
};

var someLabel = new Label("Hello World");

// one way to do it
someLabel.implement([Resizable, Draggable, Deletable]);

// another way to do it
someLabel.implement(Resizable);
someLabel.implement(Draggable);
someLabel.implement(Deletable);

It looks better and more intuitive (to me) than doing something like

var awesomeLabel = new Resizable(new Draggable(new Deletable(someLabel)));

because we are still dealing with a label, and not some resizable, or some draggable, or some deletable object. Another small point, but still worth mentioning is that the parentheses start getting unmanageable after 3 or 4 decorators, especially without good IDE support.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜