在《头第一。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
GO TO FULL VERSION