JavaRush /Java Blog /Random-TL /Pattern ng Java Decorator

Pattern ng Java Decorator

Nai-publish sa grupo
Sa aklat na “Una ang Ulo. Mga Pattern ng Disenyo" ni Eric Freeman at Elizabeth Robson ay tinukoy ito bilang mga sumusunod: Ang pattern ng Dekorador ay dynamic na nagbibigay ng mga bagong kakayahan sa isang bagay at isang alternatibo sa subclassing para sa pagpapalawak ng functionality. Subukan nating tingnan ang kahulugang ito nang mas detalyado gamit ang isang halimbawa. Ipagpalagay na lumikha ka ng isa pang modernong relihiyon at planong magbigay sa mga tao ng kaukulang serbisyo. kasi ang mga modernong uso ay nagpapatuloy sa vegetarianism, ekolohiya, pag-unlad ng tao, at sa ilang kadahilanan ang mga tao ay hindi nasisiyahan sa "tradisyonal" na mga relihiyon (o atheism sa dulo), pagkatapos ikaw, na sumusunod sa mainstream, lumikha ng isa pang New Age na relihiyon (isang uri ng synthesis mula sa umiiral na. relihiyon, kumukuha mula sa bawat isa kung ano ang gusto). Sa simula ay ibibigay mo ang mga sumusunod na serbisyo: 1. Fortune telling 2. Horoscope Ie. ganito ang hitsura ng lahat: Mayroong isang interface ng serbisyo na may presyo siyempre :) at isang paglalarawan
public interface Service {
    public double getPrice();
    public String getLabel();
}
at mga serbisyo
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;
    }
}
Kaya, naaayon, lumitaw ang 2 mga order (pagsasabi ng kapalaran sa mga Tarot card at isang personal na horoscope mula sa kliyente):
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);
}
at ang resulta ng programa:
10000.0
Magiging maayos ang lahat, ngunit mayroon nang daan-daan, kung hindi libu-libo, tulad mo, at kailangan nating patuloy na paunlarin ang espirituwalidad ng mga tao, kung hindi man ay hindi na sila interesado. Samakatuwid, ang mga karagdagang opsyon sa kasalukuyang mga serbisyo ay inaalok bilang isang opsyon. Halimbawa, kapag pumipili ng isang serbisyo sa pagsasabi ng kapalaran (Tarot o coffee grounds), bilang isang karagdagang opsyon maaari kang mag-order ng mga katangian ng chakras o aura (na may sariling gastos para sa bawat isa). Paano ito maipapatupad upang hindi makagawa ng mga pagbabago sa umiiral na mga klase ng serbisyo, kung saan ang lahat ay na-configure at nakalkula nang tama. Maaari kang lumikha ng mga karagdagang klase ng Divination + Chakras o Divination + Aura sa kasalukuyang Divination:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
o gumamit lang ng subclassing, i.e. pahabain ang klase ng magulang sa klase ng bata
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);
    }
    // Здесь своя стоимость и другие методы
}
Ngunit ang mga disadvantages ay agad na nakikita, na nagpapaunlad ng espirituwalidad ng buong mundo, maaari tayong magkaroon ng mga bagong karagdagang pagpipilian, na nangangahulugang mga bagong klase, at kung kailangan pa nating pagsamahin ang mga kasalukuyan, kung gayon ang mga klase ay lalago nang mabilis, hindi bababa sa wala na tayo. sapat na ang Fortune telling class na may dalawang opsyon na magkasama, at hindi magkahiwalay na magkahiwalay:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
Dito mo magagamit ang napaka "nagse-save" na pattern ng Dekorador sa Java. Para magawa ito, gagawa kami ng klase para sa mga karagdagang opsyon, na magpapatupad din ng Serbisyo, ngunit naglalaman din ng Serbisyo. At nang naaayon, kapag kailangan nating maglagay ng isang order para sa pagsasabi ng kapalaran at kahit na may 2 mga pagpipilian na magkasama, magiging ganito ang hitsura: Ang interface ay tulad ng sa simula pa lamang.
public interface Service {
    public double getPrice();
    public String getLabel();
}
2 klase ng mga serbisyo, katulad ng dati:
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;
    }
}
Dekorador para sa karagdagang mga pagpipilian
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();
    }
}
At ang mga pagpipilian mismo (2 sa ngayon):
public class Aura extends OptionDecorator {
    public Aura(Service service) {
        super(service, "Характеристика ауры", 1500);
    }
}
public class Chakra extends OptionDecorator {
    public Chakra(Service service) {
        super(service, "Характеристика чакр", 500);
    }
}
Well, ang order mismo
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
который дает результат суммы основной услуги и 2 дополнительных опций. А значит, не нужно на каждую доп. опцию (or их комбинацию) создавать новый класс. К тому же данные опции можно применять не только к услуге Гадание, но также и к услуге Гороскоп. Поэтому когда в ближайшем будущем нам потребуется внедрить следующие дополнительные опции: - совместимость партнеров по аватаркам в социальных сетях - улучшение денежного потока через дистанционный ченненлинг нам потребуется написать всего 2 дополнительных класса:
public class Channeling extends OptionDecorator {
    public Channeling(Service service) {
        super(service, "Полет в Поле Чудес", 99999);
    }
}
public class Avatar extends OptionDecorator {
    public Avatar(Service service) {
        super(service, "Ваша любовь в соц сетях", 5555);
    }
}
и можно добавлять их к любой услуге:
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());
}
и результат работы программы (который нам нужен):
3000.0
106554.0
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION