Frage

Vorausgesetzt ich eine Klasse namens A haben, und ich möchte den Dekorateur Design-Muster verwenden. Korrigieren Sie mich, wenn ich falsch liege, aber dafür arbeiten, werden wir einen Dekorateur-Klasse erstellen müssen, sagen ADecorator, die einen Verweis auf ein A Instanz halten, und alle anderen Dekorateure werden erweitern diese Funktionalität hinzuzufügen.

Ich verstehe nicht, warum müssen wir eine Dekorateur-Klasse erstellen, statt eine A Instanz mit?

War es hilfreich?

Lösung

Das Decorator-Muster wird verwendet, Fähigkeiten, um Objekte hinzuzufügen, dynamisch (das heißt, zur Laufzeit). Normalerweise wird das Objekt hat seine Fähigkeiten festgelegt, wenn Sie die Klasse schreiben. Aber ein wichtiger Punkt ist, dass die Funktionalität des Objekts wird in eine Art und Weise erweitert, die an den Client des Objekts transparent ist, weil es die gleiche Schnittstelle wie die ursprüngliche Objekt delegiert die Verantwortung an das eingerichtete Objekt implementiert.

Das Decorator-Muster funktioniert in Szenarien, in denen es viele optionalen Funktionen sind, die ein Objekt haben kann. Ohne die Decorator-Muster werden Sie eine andere Klasse für jede Objekt-Option Konfiguration erstellen müssen. Ein Beispiel, das ziemlich nützlich ist, stammt aus dem Head First Design Patterns Buch von O'Reilly. Es verwendet ein Coffee-Shop Beispiel, das wie Starbucks klingt.

Sie haben also den Grund Kaffee mit einem Verfahren wie Kosten.

public double cost(){
     return 3.45;
}

Dann kann der Kunde Sahne hinzufügen, die eine CoffeeCream Klasse mit der Kostenmethode 0,35, so dass Sie jetzt erstellen Kosten:

public double cost(){
    return 3.80;
}

Dann kann der Kunde Mokka wollen, die 0,5, und sie möchten Mokka mit Sahne oder Mokka ohne Creme kostet. So erstellen Sie Klassen CoffeeMochaCream und CoffeeMocha. Dann wird ein Kunde will Sahne, so dass Sie eine Klasse CoffeeCreamCream erstellen ... etc. Was Sie am Ende mit Klasse Explosion ist. Bitte entschuldigen Sie die schlechte Beispiel verwendet. Es ist ein bisschen spät, und ich weiß, es ist trivial, aber es macht den Punkt Ausdruck bringen.

Sie können stattdessen ein Element abstrakte Klasse mit einer abstrakten Kostenverfahren erstellen:

public abstract class Item{
    public abstract double cost();
}

Und Sie können eine konkrete Kaffee Klasse erstellen, die Artikel erweitert:

public class Coffee extends Item{
    public double cost(){
       return 3.45;
    }
}

Dann erstellen Sie eine CoffeeDecorator, die die gleiche Schnittstelle erweitern und enthalten ein Element aus.

public abstract class CoffeeDecorator extends Item{
     private Item item;
     ...
}

Dann können Sie konkrete Dekorateure für jede Option erstellen:

public class Mocha extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.5;
   }

}

Beachten Sie, wie der Dekorateur kümmert sich nicht darum, welche Art von Objekt es genauso lange ist die Verpackung, wie es ein Artikel ist? Es nutzt die Kosten () des Item-Objekt und fügt einfach seine eigenen Kosten.

public class Cream extends CoffeeDecorator{

   public double cost(){
     return item.cost() + 0.35;
   }

}

Jetzt ist es möglich, eine große Anzahl von Konfigurationen mit diesen wenigen Klassen: z.

 Item drink = new Cream(new Mocha(new Coffee))); //Mocha with cream

oder

 Item drink = new Cream(new Mocha(new Cream(new Coffee))));//Mocha with double cream

Und so weiter.

Andere Tipps

Ich kann nicht erklären, es besser als die wikipedia Artikel.

BTW, wenn Sie nur auf Muster am Anfang steht, ist das Head First Design Patterns Buch phänomenal . Es macht wirklich die Konzepte einfach zu verdauen, und stellt sicher, um den Kontrast und ähnliche Muster in einer Art und Weise zu vergleichen, die lächerlich einfach zu verstehen ist.

In einigen Sprachen (wie Ruby oder JavaScript) Sie könnten nur mit neuen Funktionen einer A-Instanz. Ich stelle fest, dass Ihre Frage Java markiert ist, so nehme ich an, dass Sie fragen, warum Sie nicht diese in Java tun. Der Grund dafür ist, dass Java ist statisch typisiert. Ein A-Instanz kann immer nur die Methoden, die der Klasse A definiert oder erbt. Deshalb, wenn Sie während der Laufzeit wollen eine Methode einer A-Instanz zu geben, die A nicht definiert, dann ist diese neue Methode muss in einer anderen Klasse definiert werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top