JavaRush /Java-Blog /Random-DE /Java-Decorator-Muster

Java-Decorator-Muster

Veröffentlicht in der Gruppe Random-DE
Im Buch „Kopf voran. „Design Patterns“ von Eric Freeman und Elizabeth Robson definiert es wie folgt: Das Decorator-Muster stellt einem Objekt dynamisch neue Fähigkeiten zur Verfügung und ist eine Alternative zur Unterklassenbildung zur Erweiterung der Funktionalität. Versuchen wir, diese Definition anhand eines Beispiels genauer zu betrachten. Angenommen, Sie haben eine weitere moderne Religion geschaffen und planen, den Menschen die entsprechenden Dienste anzubieten. Weil современные тенденции преследуют вегетарианство, экологию, развитие человека, а «традиционные» религии (oder атеизм в конце концов) людей почему-то не устраивают, то вы следуя мейнстриму создаете очередную религию New Age (некий синтез из имеющихся религий, взяв с каждой то что gefällt). Zu Beginn erbringen Sie folgende Leistungen: 1. Wahrsagerei 2. Horoskop Dh. Alles sieht so aus: Es gibt eine Service-Schnittstelle mit einem Preis natürlich :) und einer Beschreibung
public interface Service {
    public double getPrice();
    public String getLabel();
}
und Dienstleistungen
public class Divination implements Service {
    private String label;
    private double price;

    public Divination(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
public class Horoscope implements Service {
    private String label;
    private double price;

    public Horoscope(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
Nun, dementsprechend erschienen 2 Befehle (Wahrsagerei mit Tarotkarten und einem persönlichen Horoskop des Kunden):
public static void main(String[] args) {
    double cost;
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    // И персональный гороскоп
    Service personalHoroscope = new Horoscope("Персональный гороскоп", 9000);
    cost = taro.getPrice() + personalHoroscope.getPrice();

    System.out.println(cost);
}
und das Ergebnis des Programms:
10000.0
Alles wäre gut, aber es gibt bereits Hunderte, wenn nicht Tausende wie Sie, und wir müssen die Spiritualität der Menschen weiterentwickeln, sonst haben sie kein Interesse mehr. Daher wurden optional Zusatzoptionen zu den bisherigen Leistungen angeboten. Wenn Sie sich beispielsweise für einen Wahrsagedienst (Tarot oder Kaffeesatz) entscheiden, können Sie als zusätzliche Option die Eigenschaften der Chakren oder der Aura bestellen (jeweils mit eigenen Kosten). Wie könnte dies umgesetzt werden, um keine Änderungen an den bestehenden Serviceklassen vorzunehmen, in denen bereits alles korrekt konfiguriert und berechnet ist? Sie können zur aktuellen Wahrsagerei zusätzliche Klassen Wahrsagen + Chakren oder Wahrsagen + Aura erstellen:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
oder verwenden Sie einfach Unterklassen, d. h. Erweitern Sie die übergeordnete Klasse auf die untergeordnete Klasse
public class DivinationWithAura extends Divination {
    public DivinationWithAura(String label, double price) {
        super(label, price);
    }
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras extends Divination {
    public DivinationWithChakras(String label, double price) {
        super(label, price);
    }
    // Здесь своя стоимость и другие методы
}
Aber die Nachteile sind sofort sichtbar, die Entwicklung der Spiritualität auf der ganzen Welt, wir haben möglicherweise neue zusätzliche Optionen, das heißt neue Klassen, und wenn wir bestehende noch kombinieren müssen, dann werden die Klassen schnell wachsen, zumindest haben wir keine mehr Genug von der Wahrsagerei-Klasse mit zwei Optionen zusammen und nicht getrennt voneinander:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
Hier können Sie das sehr „sparsame“ Decorator-Muster in Java verwenden. Dazu erstellen wir eine Klasse für zusätzliche Optionen, die ebenfalls Service implementiert, aber auch Service enthält. Und dementsprechend sieht es so aus, wenn wir eine Bestellung für eine Wahrsagerei aufgeben müssen, und das sogar mit zwei Optionen zusammen: Die Benutzeroberfläche ist so, wie sie von Anfang an war
public interface Service {
    public double getPrice();
    public String getLabel();
}
2 Leistungsklassen, die gleichen wie zuvor:
public class Divination implements Service {
    private String label;
    private double price;

    public Divination(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
public class Horoscope implements Service {
    private String label;
    private double price;

    public Horoscope(String label, double price) {
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price;
    }

    public String getLabel() {
        return this.label;
    }
}
Dekorateur für zusätzliche Optionen
public class OptionDecorator implements Service {
    private Service service;
    private String label;
    private double price;

    public OptionDecorator(Service service, String label, double price) {
        this.service = service;
        this.label = label;
        this.price = price;
    }

    public double getPrice() {
        return this.price + service.getPrice();
    }

    public String getLabel() {
        return this.label + service.getLabel();
    }
}
Und die Optionen selbst (bisher 2):
public class Aura extends OptionDecorator {
    public Aura(Service service) {
        super(service, "Характеристика ауры", 1500);
    }
}
public class Chakra extends OptionDecorator {
    public Chakra(Service service) {
        super(service, "Характеристика чакр", 500);
    }
}
Nun, die Bestellung selbst
public static void main(String[] args) {
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    Service chakra = new Chakra(taro);
    Service aura = new Aura(chakra);

    // И общая стоимость
    System.out.println(aura.getPrice());
}
3000.0
was das Ergebnis der Summe der Hauptleistung und 2 Zusatzoptionen ergibt. Das heißt, es ist nicht jedes weitere nötig Option (oder eine Kombination aus beiden), um eine neue Klasse zu erstellen. Darüber hinaus können diese Optionen nicht nur auf den Wahrsagedienst, sondern auch auf den Horoskopdienst angewendet werden. Wenn wir daher in naher Zukunft die folgenden zusätzlichen Optionen implementieren müssen: - Kompatibilität von Avatar-Partnern in sozialen Netzwerken - Verbesserung des Cashflows durch Fernkanalisierung, müssen wir nur zwei zusätzliche Klassen schreiben:
public class Channeling extends OptionDecorator {
    public Channeling(Service service) {
        super(service, "Полет в Поле Чудес", 99999);
    }
}
public class Avatar extends OptionDecorator {
    public Avatar(Service service) {
        super(service, "Ваша любовь в соц сетях", 5555);
    }
}
und Sie können sie zu jedem Dienst hinzufügen:
public static void main(String[] args) {
    // Гадание на Таро
    Service taro = new Divination("Таро", 1000);
    Service chakra = new Chakra(taro);
    Service aura = new Aura(chakra);

    // И общая стоимость
    System.out.println(aura.getPrice());

    // Гороскоп
    Service horoscope = new Horoscope("Персональный гороскоп", 1000);
    Service channenling = new Channeling(horoscope);
    Service avatar = new Avatar(channenling);

    // И общая стоимость
    System.out.println(avatar.getPrice());
}
und das Ergebnis des Programms (das wir brauchen):
3000.0
106554.0
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION