JavaRush /Java Blog /Random-TW /Java 裝飾器模式

Java 裝飾器模式

在 Random-TW 群組發布
在《頭第一。Eric Freeman 和 Elizabeth Robson 所寫的《設計模式》將其定義如下: 裝飾器模式動態地為物件提供新功能,並且是用於擴展功能的子類化的替代方案。 讓我們嘗試使用範例更詳細地了解此定義。假設你又創造了另一個現代宗教,並計劃為人們提供相應的服務。因為 現代潮流追求素食、生態、人類發展,而出於某種原因,人們對「傳統」宗教(或最終的無神論)不滿意,那麼你就跟隨主流,創造另一種新時代宗教(現有宗教的某種綜合) ,從每個喜歡的東西中獲取)。一開始您提供以下服務:1.算命2.星座即。一切看起來都是這樣的:有一個服務介面,當然有價格:)和描述
public interface Service {
    public double getPrice();
    public String getLabel();
}
和服務
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;
    }
}
好吧,相應地,出現了 2 個命令(用塔羅牌算命和客戶的個人星座):
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);
}
以及程序的結果:
10000.0
一切都會好起來的,但已經有數百人,甚至數千人像你一樣,我們需要繼續發展人們的靈性,否則他們不再感興趣。因此,提供了當前服務的附加選項作為選項。例如,當選擇算命服務(塔羅牌或咖啡渣)時,作為附加選項,您可以訂購脈輪或光環的特徵(每個都有自己的成本)。如何實現這一點,以免對現有服務類別進行更改,其中所有內容都已正確配置和計算。您可以為當前占卜創建額外的類別占卜+脈輪或占卜+光環:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
或只是使用子類化,即 將父類別擴展到子類
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);
    }
    // Здесь своя стоимость и другие методы
}
但缺點也是立竿見影的,發展整個世界的靈性,我們可能會有新的附加選擇,這意味著新的職業,如果我們還需要結合現有的,那麼職業會快速增長,至少我們不再有足夠的算命類別有兩個選項在一起,而不是單獨分開:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
在這裡您可以使用 Java 中非常「節省」的裝飾器模式。為此,我們將為附加選項建立一個類,該類別也將實作 Service,但也包含 Service。相應地,當我們需要下單算命的時候,即使有2個選項在一起,也會是這樣的: 介面一開始就是這樣的
public interface Service {
    public double getPrice();
    public String getLabel();
}
2類服務,與之前相同:
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;
    }
}
用於附加選項的裝飾器
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();
    }
}
以及選項本身(到目前為止有 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);
    }
}
好吧,訂單本身
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 個附加選項總和的結果。這意味著不需要每一個額外的 選項(或兩者的組合)來建立新類別。此外,這些選項不僅可以應用於算命服務,還可以應用於星座服務。因此,當在不久的將來我們需要實現以下附加選項時: - 社交網路上頭像合作夥伴的兼容性 - 透過遠端通道改善現金流,我們只需要編寫 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
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION