这是一个很好的javascript装饰模式吗?

时间:2010-05-10 15:41:14

标签: javascript decorator

我需要一些简单的对象,以后会变得更复杂,有许多不同的属性,所以我想到了装饰模式。 我这样看着Crockford的幂构造函数和对象增强:

//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 decorated
var myObj = simpleDecorator(obj, "aParam");

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

这是在javascript中使用装饰器模式的好方法吗? 还有其他更好的方法吗?

1 个答案:

答案 0 :(得分:9)

Wikipedia和其他网站上的Javascript中有各种各样的Decorator模式实现 - (1)(2)(3)。该模式定义为:

装饰器模式是一种设计模式,允许动态地将新/附加行为添加到现有对象。

对象扩展已经构建到语言本身中。可以轻松扩展对象,并可以随时添加属性。那你为什么要跳过篮球来实现呢?不应该这样的事情就足够了:

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!");

如果要将方法应用于使用此函数创建的所有对象,请将该方法/属性添加到函数的原型中。

更新:如果您有明确定义的功能,可以根据需要混合并匹配到某些类型的对象中,那么MooTools extending方法mixing和{ {3}}行为很好地完成了对象。举一个例子,考虑一个可以调整大小,用手柄拖动并通过单击右上角的刻度标记删除的UI组件。您可能不希望使用这些行为创建每个组件,而是将所有这些行为分别定义到它们自己的对象中。然后根据需要将这些行为混合到每种类型的组件中。

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);

它看起来比做

之类的东西更好,更直观(对我而言)
var awesomeLabel = new Resizable(new Draggable(new Deletable(someLabel)));

因为我们仍在处理一个标签,而不是一些可调整大小的,或一些可拖动的,或一些可删除的对象。另一个小问题,但仍然值得一提的是,在3或4个装饰器后,括号开始变得无法管理,特别是没有良好的IDE支持。