2010-05-10 2 views
8

Мне нужны некоторые простые объекты, которые могут стать более сложными позже, со множеством разных свойств, поэтому я подумал о шаблоне декоратора. Я сделал это, глядя на Крокфорд в конструкторе мощности и объекта увеличения:Является ли это хорошим шаблоном декоратора для javascript?

//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

Этот способ программирования кажется довольно непригодным для меня и запутанным, но, возможно, я единственный ... – Harmen

+2

Есть ли какая-то причина использовать этот шаблон, отличный от «эти объекты могут быть более сложными в какой-то момент в будущем «? – Mathew

+0

Эти объекты * являются более сложными в некоторой точке * сейчас *. Поэтому, если мне нужны некоторые объекты, которые должны быть простыми и другими объектами, которые должны быть более сложными, я не хочу создавать множество разных объектов, я увеличу сложность любого отдельного объекта, используя некоторые определенные свойства. Подумайте о пользовательских интерфейсах, если вы создаете другой объект для каждой комбинации элементов интерфейса, у вас есть комбинационный взрыв. Здесь этот шаблон может помочь вам лучше разработать код. –

ответ

8

Существуют различные реализации шаблона Decorator в Javascript на Wikipedia и на других сайтах - (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!"); 

Если вы хотите метод применить ко всем объектам, которые были созданы с помощью этой функции, а затем добавить, что метод/свойства прототипа функции.

Update: Если вы четко определили функциональные части, которые могут быть смешаны и подобраны по мере необходимости в определенные типы объектов, то MooTools подход extending и mixing поведения в объекты красиво сделан. Чтобы привести пример, рассмотрите компонент пользовательского интерфейса, который можно изменить, перетащить с помощью дескриптора и удалить, щелкнув галочку в правом верхнем углу. Возможно, вам не захочется создавать каждый компонент с этими поведением, но каждый из этих действий каждый раз определяет каждое из них в свой собственный объект. И позже смешайте эти поведения в каждом типе компонента по мере необходимости.

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.

+0

Да, я думал, что декоратор в javascript не кажется действительно полезным в большинстве случаев. Но подумайте об объектах, управляющих пользовательским интерфейсом. Если я начну с простых объектов для базовых интерфейсов, а затем я хочу добавить динамически некоторые определенные функции, например изменить размер или изменить цвет или другие, но не все вместе, например, используя наследование, как раз на объекте, который я хочу, я думаю, что узор декоратора должны быть полезными.Это позволяет избежать комбинационного взрыва параметров объекта, и вы можете добавить новый сложный декоратор, когда он вам понадобится, без необходимости изменять каждый отдельный объект. –

+0

Я долго думал об этом .. TWSS и пришел к выводу, что декоратор и миксины очень похожи. Mixin расширяет функциональные возможности объекта и не обязательно изменяет поведение только базового объекта. И, глядя на это с этой точки зрения, мне очень нравится, как это делает MooTools. Обновление ответа с дополнительной информацией об этом. – Anurag

Смежные вопросы