Действительно ли это - хороший шаблон "декоратор" для JavaScript?

Мне нужны некоторые простые объекты, которые могли стать более сложными позже со многими различными свойствами, таким образом, я думал к шаблону "декоратор". Я сделал это рассмотрение конструктора питания 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? Там другие лучшие пути состоят в том, чтобы сделать это?

8
задан Manuel Bitto 10 May 2010 в 15:41
поделиться

1 ответ

Существуют различные реализации шаблона Decorator в Javascript на Википедии и на других сайтах - (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 из расширяет и смешивание поведения с объектами сделано хорошо. В качестве примера рассмотрим компонент пользовательского интерфейса, размер которого можно изменять, перетаскивать с помощью ручки и удалять, щелкнув галочку в правом верхнем углу. Возможно, вы не захотите создавать каждый компонент с этим поведением, но определите все эти поведения отдельно, каждое в свой собственный объект. А позже при необходимости смешайте это поведение с каждым типом компонента.

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.

9
ответ дан 5 December 2019 в 18:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: