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

Man*_*tto 8 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);
Run Code Online (Sandbox Code Playgroud)

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

Anu*_*rag 9

维基百科和其他网站上的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!");
Run Code Online (Sandbox Code Playgroud)

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

更新:如果你有明确规定的功能块也可以根据需要为某些类型的对象的混合和匹配,那么MooTools的的方法扩展混合的行为为对象是很好做.举一个例子,考虑一个可以调整大小,用手柄拖动并通过单击右上角的刻度标记删除的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);
Run Code Online (Sandbox Code Playgroud)

它看起来比做某些事情更好,更直观(对我而言)

var awesomeLabel = new Resizable(new Draggable(new Deletable(someLabel)));
Run Code Online (Sandbox Code Playgroud)

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