JavaRush /Blogue Java /Random-PT /Padrão de decorador Java

Padrão de decorador Java

Publicado no grupo Random-PT
No livro “De cabeça. Design Patterns”, de Eric Freeman e Elizabeth Robson, define-o da seguinte forma: O padrão Decorator fornece dinamicamente novos recursos para um objeto e é uma alternativa à subclasse para estender a funcionalidade. Vamos tentar examinar esta definição com mais detalhes usando um exemplo. Suponha que você tenha criado mais uma religião moderna e planeje fornecer às pessoas os serviços correspondentes. Porque as tendências modernas perseguem o vegetarianismo, a ecologia, o desenvolvimento humano e, por alguma razão, as pessoas não estão satisfeitas com as religiões “tradicionais” (ou o ateísmo no final), então você, seguindo a corrente principal, cria outra religião da Nova Era (uma espécie de síntese da existente religiões, tirando de cada uma o que quiser). No início você fornece os seguintes serviços: 1. Adivinhação 2. Horóscopo Ou seja. tudo fica assim: Existe uma interface de serviço com um preço, claro :) e uma descrição
public interface Service {
    public double getPrice();
    public String getLabel();
}
e serviços
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;
    }
}
Pois bem, surgiram 2 pedidos (adivinhação com cartas de Tarô e horóscopo pessoal do 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 o resultado do programa:
10000.0
Tudo ficaria bem, mas já existem centenas, senão milhares, como você, e precisamos continuar desenvolvendo a espiritualidade das pessoas, caso contrário elas não se interessarão mais. Portanto, opções adicionais aos serviços atuais foram oferecidas como opção. Por exemplo, ao escolher um serviço de adivinhação (Tarot ou borra de café), como opção adicional você pode solicitar as características dos chakras ou da aura (com custo próprio para cada um). Como isso poderia ser implementado para não fazer alterações nas classes de serviço existentes, onde tudo já está configurado e calculado corretamente. Você pode criar classes adicionais de Adivinhação + Chakras ou Adivinhação + Aura para a Adivinhação atual:
public class Divination implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithChakras implements Service {
    // Здесь своя стоимость и другие методы
}
public class DivinationWithAura implements Service {
    // Здесь своя стоимость и другие методы
}
ou apenas use subclasses, ou seja, estender a classe pai para a classe filha
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);
    }
    // Здесь своя стоимость и другие методы
}
Mas as desvantagens são imediatamente visíveis, desenvolvendo a espiritualidade de todo o mundo, podemos ter novas opções adicionais, o que significa novas aulas, e se ainda precisarmos combinar as atuais, então as aulas vão crescer rapidamente, pelo menos não temos mais chega da aula de adivinhação com duas opções juntas, e não separadamente:
public class DivinationWithChakrasAndAura implements Service {
    // Здесь своя стоимость и другие методы
}
É aqui que você pode usar o padrão Decorator de “salvação” em Java. Para fazer isso, criaremos uma classe para opções adicionais, que também implementará Service, mas também conterá Service. E consequentemente, quando precisarmos fazer um pedido de leitura da sorte e mesmo com 2 opções juntas, ficará assim: A interface é como era desde o início
public interface Service {
    public double getPrice();
    public String getLabel();
}
2 classes de serviços, as mesmas de antes:
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;
    }
}
Decorador para opções adicionais
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 as próprias opções (2 até agora):
public class Aura extends OptionDecorator {
    public Aura(Service service) {
        super(service, "Характеристика ауры", 1500);
    }
}
public class Chakra extends OptionDecorator {
    public Chakra(Service service) {
        super(service, "Характеристика чакр", 500);
    }
}
Bem, a ordem em si
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
que dá o resultado da soma do serviço principal e 2 opções adicionais. Isto significa que não há necessidade de cada adicional opção (ou uma combinação de ambas) para criar uma nova classe. Além disso, essas opções podem ser aplicadas não apenas ao serviço de adivinhação, mas também ao serviço de horóscopo. Portanto, quando num futuro próximo precisarmos implementar as seguintes opções adicionais: - compatibilidade de avatares parceiros nas redes sociais - melhorar o fluxo de caixa através da canalização remota, precisaremos escrever apenas 2 classes adicionais:
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 você pode adicioná-los a qualquer serviço:
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 o resultado do programa (que precisamos):
3000.0
106554.0
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION