代码之家  ›  专栏  ›  技术社区  ›  Manuel Bitto

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

  •  9
  • Manuel Bitto  · 技术社区  · 16 年前

    我需要一些简单的对象,这些对象在以后可能变得更复杂,具有许多不同的属性,所以我考虑使用装饰图案。 我看了一下Crockford的Power构造器和对象增强:

    //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中使用decorator模式是一个好方法吗? 还有其他更好的方法吗?

    1 回复  |  直到 16 年前
        1
  •  9
  •   Anurag    16 年前

    在上的javascript中有多种装饰器模式的实现 Wikipedia 和其他站点- (1) , (2) , (3) 。模式定义为:

    decorator模式是一种设计模式,允许将新的/附加的行为动态添加到现有对象中。

    对象扩展已经内置到语言本身中。对象可以很容易地扩展,属性可以随时添加。那么,你为什么要跳过铁环才能做到这一点呢?这样的事情不足以:

    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 对于对象的行为来说是很好的。为了给出一个例子,考虑一个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支持。

    推荐文章