2010-05-10 10 views
8

Ich brauche einige einfache Objekte, die später mit vielen verschiedenen Eigenschaften komplexer werden könnten, also dachte ich an Dekorationsmuster. Ich habe dies bei Crockford Macht Konstruktor und Objektvergrößerung suchen:Ist das ein gutes Dekorationsmuster für 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); 

Ist dies ein guter Weg, Decorator-Muster in Javascript haben? Gibt es andere bessere Möglichkeiten, dies zu tun?

+1

Diese Art der Programmierung scheint ziemlich unbrauchbar und verwirrend für mich, aber vielleicht bin ich der einzige ... – Harmen

+2

Gibt es einen Grund, dieses Muster zu verwenden, außer "diese Objekte können irgendwann in der Zukunft komplexer sein "? – Mathew

+0

Diese Objekte * sind * irgendwann * komplexer *. Also, wenn ich einige Objekte brauche, die einfach sein müssen und andere Objekte, die komplexer sein sollten, möchte ich nicht viele verschiedene Objekte erstellen, ich werde die Komplexität jedes einzelnen Objekts erhöhen, indem ich einige definierte Eigenschaften verwende. Denken Sie an Benutzeroberflächen, wenn Sie für jede unterschiedliche Kombination von UI-Elementen ein anderes Objekt mit einer kombinatorischen Explosion erstellen. Hier könnte Ihnen dieses Muster helfen, Code besser zu gestalten. –

Antwort

8

Es gibt verschiedene Implementierungen des Dekorierermuster in Javascript auf Wikipedia und anderen Websites - (1), (2), (3). Das Muster ist definiert als:

Das Dekorationsmuster ist ein Entwurfsmuster, mit dem neues/zusätzliches Verhalten dynamisch zu einem vorhandenen Objekt hinzugefügt werden kann.

Die Objekterweiterung ist bereits in die Sprache selbst integriert. Objekte können einfach erweitert werden und Eigenschaften können jederzeit hinzugefügt werden. Warum also sollten Sie durch Reifen springen müssen, um dies zu erreichen? Sollte nicht so etwas wie dieses genügen:

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

Wenn Sie eine Methode wollen auf alle Objekte anwenden, die diese Funktion erstellt wurden, fügen Sie dann diese Methode/Eigenschaften der Prototyp der Funktion.

aktualisieren: Wenn Sie klar Stücke von Funktionalität definiert haben, die gemischt werden können und angepasst, wie in allen Arten von Objekten benötigt, dann ist die MooTools Ansatz von extending und mixing im Verhalten in Objekte ist schön gemacht. Um ein Beispiel zu geben, betrachten Sie eine UI-Komponente, deren Größe geändert werden kann, die mit einem Ziehpunkt gezogen und durch Klicken auf ein Häkchen in der oberen rechten Ecke gelöscht werden kann. Sie möchten möglicherweise nicht jede Komponente mit diesen Verhaltensweisen erstellen, sondern alle diese Verhaltensweisen getrennt für jeweils ein eigenes Objekt definieren. Und später fügen Sie diese Verhaltensweisen bei Bedarf in jeden Komponententyp ein.

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

Es sieht besser aus und intuitives (für mich) als etwas zu tun, wie

var awesomeLabel = new Resizable(new Draggable(new Deletable(someLabel))); 

weil wir noch mit einem Etikett zu tun haben, und nicht einig veränderbare oder etwas ziehbar oder etwas löschbar Objekt . Ein weiterer kleiner Punkt, aber immer noch erwähnenswert ist, dass die Klammern nach 3 oder 4 Dekoratoren nicht mehr handhabbar sind, besonders ohne gute IDE-Unterstützung.

+0

Ja, ich dachte, dass Dekorateur in Javascript in den meisten Fällen nicht wirklich hilfreich ist. Denken Sie jedoch über Objekte nach, die die Benutzeroberfläche verwalten. Wenn ich mit einfachen Objekten für grundlegende Schnittstellen anfange, und dann möchte ich einige definierte Funktionalität, wie Größe ändern oder Farbe oder andere, aber nicht alle zusammen hinzufügen, wie Vererbung, nur auf das Objekt, das ich will, ich denke Decorator-Muster sollte nützlich sein.Es vermeidet die kombinatorische Explosion von Objektoptionen und Sie können einen neuen komplexen Dekorator hinzufügen, wenn Sie es benötigen, ohne jedes einzelne Objekt modifizieren zu müssen. –

+0

Ich habe lange und gründlich darüber nachgedacht .. TWSS, und kommen zu dem Schluss, dass Dekorateur und Mixins sehr ähnlich sind. Ein Mixin erweitert die Funktionalität eines Objekts und ändert nicht notwendigerweise nur das Verhalten des Basisobjekts. Und wenn ich es aus dieser Perspektive betrachte, mag ich die Art, wie MooTools es macht. Aktualisierung der Antwort mit mehr Infos dazu. – Anurag

Verwandte Themen