2010-04-06 7 views

Antwort

9

Ein Mixin ist geeignet, wenn Sie Ihrer Klasse etwas Verhalten hinzufügen. z.B. die Möglichkeit, im Falle eines Sammlungs-Typs aufzuzählen. Sie können so viele Verhaltensweisen in Ihre Klasse einbinden, wie Sie möchten. Es ist eine nette Möglichkeit, den üblichen Code wiederzuverwenden; Sie erhalten grundsätzlich eine Reihe von Methoden kostenlos.

Ein Dekorateur auf der anderen Seite ist eher ein hinterhältiger Abfangjäger. Es stellt die gleiche öffentliche Schnittstelle wie das Zielobjekt bereit und enthält ein Zielobjekt, an das alle Clientaufrufe delegiert werden. Allerdings dekoriert es den Anruf mit einigen Vor- und/oder Nachbearbeitungen. z.B. Wenn ich Code für eine MyCollection schreibe, möchte ich, dass alle Aufrufe dieses Typs protokolliert werden. Ich könnte einen neuen Decorator MyCollectionWithTimeStampedLogging ableiten, die beide von einer ICollection-Basis stammen, so dass sie mit dem Client identisch aussehen. Der Decorator würde eine Instanz von ICollection als einen Ctor-Parameter nehmen und Aufrufe an ihn delegieren. z.B. Add würde so aussehen

public void Add(int item) 
{ 
    _logger.log(String.Format("{0} Add called with param {1}", DateTime.Now, item.ToString()); 
    _collection.Add(item); 
    _logger.log(String.Format("{0} Add completed with param {1}", DateTime.Now, item.ToString()); 
} 
+0

Ein Dekorator ist also ein bisschen näher an dem, was Aspect Oriented Programming (AOP) tut, und ein Mixin ändert nur Ihre bestehenden Klassen? – leeand00

+0

@ leeand00 - Art von; AOP ist viel mehr als nur Dekorateure, denke ich. Mixins sind in dynamischen Sprachen vorherrschend, mit einem Mixin "mischen" Sie eine Reihe von Methoden in Ihre Klassendefinition ein. z.B. Sie können Load- und Save-Implementierungen (die eine Klasse widerspiegeln und öffentliche Eigenschaften auf Datenträger schreiben/schreiben) in ein Modul Persistable schreiben und dann in mehrere Klassen einmischen. Alle diese Klassen können jetzt auf Festplatte gespeichert werden. – Gishu

+0

Mit AOP (mit denen ich vertraut bin als ... sagen Mixins) können Sie 3 verschiedene Dinge, die mit den ausgewählten Schnittstellen passieren können, angeben, Sie können eine Pre-Aktion, eine Post-Aktion und eine statt-von angeben Aktion. – leeand00

2

Ich bin mir nicht sicher, ob ich der Aussage zustimme, dass Decorator zur Laufzeit erweitert wird. Ich weiß, das ist, was Wikipedia sagt, aber ich denke nicht, dass es genau ist. Ich würde vorschlagen, die GoF-Definition des Decorator-Musters zu lesen. Es ist eine dynamische Erweiterung, ja, aber es muss sicherlich nicht zur Laufzeit sein.

+2

Es muss nicht sein, aber es kann sein. – leeand00

12

Wenn Sie das Dekoratormuster verwenden, kapseln Sie im Allgemeinen die Basisklasse ein, anstatt sie zu erweitern (oder zu mischen). Häufig tun Sie dies, weil Sie die Funktionalität der Klasse verwenden möchten, aber Sie möchten die Anrufe in die Klasse umwandeln, sodass Sie vor oder nach dem Anruf einige zusätzliche Schritte ausführen können. Betrachten wir ein LoggerDecorator

public class LoggerDecorator implements SomeInterface { 
     private SomeInterface delegate; 
     public void someMethod() { 
      LOGGER.debug("someMethod called"); 
      delegate.someMethod(); 
     } 
} 

Sie wollen nicht wirklich den Delegierten belichten, aber Sie wollen ihre Funktionalität nutzen. Also, ob Sie uns Mixins, eine Klasse erweitern oder dekorieren, hängt wirklich davon ab, was Sie zu tun versuchen. Erweitern Sie eine Klasse und fügen Sie ihr neue Funktionen hinzu? Oder wickelst du die Klasse ein?

+0

@Jeff Bitte sehen Sie, was ich unten in Gishus Beitrag kommentiert habe und sagen Sie mir, ob ich es habe oder nicht. – leeand00

+0

Ich denke, Sie sind auf der richtigen Spur, aber AOP ist ein dynamisches Interceptor-Framework, das zur Laufzeit auftritt (oder Kompilierzeit, wenn Sie mit aspectj kompilieren). Im Allgemeinen würde ich empfehlen, die Decorator-Route zu gehen, es sei denn, Sie benötigen AOP, weil die Laufzeit-Injektion viel spröder sein kann, wenn Sie nicht vorsichtig sind. –