JavaRush /Java Blog /Random-IT /Modello decoratore Java

Modello decoratore Java

Pubblicato nel gruppo Random-IT
Nel libro “A testa in giù. Design Patterns” di Eric Freeman ed Elizabeth Robson lo definisce come segue: Il pattern Decorator fornisce dinamicamente nuove funzionalità a un oggetto ed è un'alternativa alla sottoclasse per estendere le funzionalità. Proviamo a vedere questa definizione più in dettaglio usando un esempio. Supponiamo di aver creato un'altra religione moderna e di voler fornire alle persone i servizi corrispondenti. Perché le tendenze moderne perseguono il vegetarianismo, l'ecologia, lo sviluppo umano, e per qualche motivo le persone non sono soddisfatte delle religioni "tradizionali" (o dell'ateismo alla fine), allora tu, seguendo la corrente principale, crei un'altra religione New Age (una sorta di sintesi delle religioni esistenti) religioni, prendendo da ciascuna ciò che piace). All'inizio fornisci i seguenti servizi: 1. Cartomanzia 2. Oroscopo Cioè. tutto assomiglia a questo: c'è un'interfaccia di servizio con un prezzo ovviamente :) e una descrizione
public interface Service {
    public double getPrice();
    public String getLabel();
}
e servizi
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;
    }
}
Ebbene, di conseguenza, sono apparsi 2 ordini (cartomanzia con le carte dei Tarocchi e un oroscopo personale del cliente):
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);
}
e il risultato del programma:
10000.0
Andrebbe tutto bene, ma sono già centinaia, se non migliaia, come te, e dobbiamo continuare a sviluppare la spiritualità delle persone, altrimenti non sono più interessate. Pertanto sono state offerte opzioni aggiuntive ai servizi attuali come opzione. Ad esempio, quando si sceglie un servizio di cartomanzia (Tarocchi o fondi di caffè), come opzione aggiuntiva è possibile ordinare le caratteristiche dei chakra o dell'aura (con il proprio costo per ciascuno). Come potrebbe essere implementato per non apportare modifiche alle classi di servizio esistenti, dove tutto è già configurato e calcolato correttamente. Puoi creare classi aggiuntive Divinazione + Chakra o Divinazione + Aura all'attuale Divinazione:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
o semplicemente usa la sottoclasse, ad es. estendere la classe genitore alla classe figlia
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);
    }
    // Здесь своя стоимость и другие методы
}
Ma gli svantaggi sono immediatamente visibili, sviluppando la spiritualità del mondo intero, potremmo avere nuove opzioni aggiuntive, il che significa nuove classi, e se abbiamo ancora bisogno di combinare quelle attuali, allora le classi cresceranno rapidamente, almeno non abbiamo più abbastanza della lezione di cartomanzia con due opzioni insieme e non separatamente separatamente:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
Qui è dove puoi utilizzare il modello Decorator molto "salvavita" in Java. Per fare ciò, creeremo una classe per opzioni aggiuntive, che implementerà anche Service, ma conterrà anche Service. E di conseguenza, quando dobbiamo effettuare un ordine per la predizione del futuro e anche con 2 opzioni insieme, apparirà così: L'interfaccia è com'era fin dall'inizio
public interface Service {
    public double getPrice();
    public String getLabel();
}
2 classi di servizi, le stesse di prima:
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;
    }
}
Decoratore per opzioni aggiuntive
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();
    }
}
E le opzioni stesse (2 finora):
public class Aura extends OptionDecorator {
    public Aura(Service service) {
        super(service, "Характеристика ауры", 1500);
    }
}
public class Chakra extends OptionDecorator {
    public Chakra(Service service) {
        super(service, "Характеристика чакр", 500);
    }
}
Ebbene, l'ordine stesso
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
che dà il risultato della somma del servizio principale e di 2 opzioni aggiuntive. Ciò significa che non è necessario alcun ulteriore opzione (o una combinazione di entrambe) per creare una nuova classe. Inoltre, queste opzioni possono essere applicate non solo al servizio di cartomanzia, ma anche al servizio di oroscopo. Pertanto, quando nel prossimo futuro avremo bisogno di implementare le seguenti opzioni aggiuntive: - compatibilità dei partner avatar sui social network - miglioramento del flusso di cassa attraverso la canalizzazione remota, dovremo scrivere solo 2 classi aggiuntive:
public class Channeling extends OptionDecorator {
    public Channeling(Service service) {
        super(service, "Полет в Поле Чудес", 99999);
    }
}
public class Avatar extends OptionDecorator {
    public Avatar(Service service) {
        super(service, "Ваша любовь в соц сетях", 5555);
    }
}
e puoi aggiungerli a qualsiasi servizio:
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());
}
e il risultato del programma (di cui abbiamo bisogno):
3000.0
106554.0
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION