O padr
Padrão de Design Decorator
Nós usamos a herança ou composição para estender o comportamento de um objeto, mas isso é feito em tempo de compilação e é aplicável a todas as instâncias da classe. Não podemos adicionar nenhuma nova funcionalidade ou remover qualquer comportamento existente em tempo de execução – é aí que o padrão Decorator entra em cena. Suponha que queiramos implementar diferentes tipos de carros – podemos criar a interface Car para definir o método de montagem e, em seguida, podemos ter um carro básico, e ainda mais, podemos estendê-lo para Carro Esportivo e Carro de Luxo. A hierarquia de implementação será parecida com a imagem abaixo. Mas se quisermos obter um carro em tempo de execução que tenha tanto as características de um carro esportivo quanto de um carro de luxo, a implementação fica complexa e se quisermos especificar quais características devem ser adicionadas primeiro, fica ainda mais complexo. Agora, imagine se tivermos dez tipos diferentes de carros, a lógica de implementação usando herança e composição será impossível de gerenciar. Para resolver esse tipo de situação de programação, aplicamos o padrão decorador em Java. Precisamos ter os seguintes tipos para implementar o padrão de design do decorador.
-
Interface de Componente – A interface ou classe abstrata que define os métodos que serão implementados. No nosso caso,
Carro
será a interface do componente.package com.journaldev.design.decorator; public interface Carro { public void montar(); }
-
Implementação de Componente – A implementação básica da interface do componente. Podemos ter a classe
CarroBasico
como nossa implementação de componente.package com.journaldev.design.decorator; public class CarroBasico implements Carro { @Override public void montar() { System.out.print("Carro Básico."); } }
-
Decorador – A classe Decorador implementa a interface do componente e tem uma relação HAS-A com a interface do componente. A variável de componente deve ser acessível às classes de decorador filho, então faremos essa variável protegida.
pacote com.journaldev.design.decorator; public class CarDecorator implements Car { protected Car car; public CarDecorator(Car c){ this.car=c; } @Override public void montar() { this.car.montar(); } }
-
Decoradores Concretos – Estendendo a funcionalidade do decorador base e modificando o comportamento do componente conforme necessário. Podemos ter classes de decoradores concretos como
CarroLuxo
eCarroEsportivo
.pacote com.journaldev.design.decorator; public class CarroEsportivo extends CarDecorator { public CarroEsportivo(Car c) { super(c); } @Override public void montar(){ super.montar(); System.out.print(" Adicionando características do Carro Esportivo."); } }
pacote com.journaldev.design.decorator; public class CarroLuxo extends CarDecorator { public CarroLuxo(Car c) { super(c); } @Override public void montar(){ super.montar(); System.out.print(" Adicionando características do Carro de Luxo."); } }
Padrão de Projeto Decorator – Diagrama de Classe
Programa de Teste do Padrão de Projeto Decorator
package com.journaldev.design.test;
import com.journaldev.design.decorator.BasicCar;
import com.journaldev.design.decorator.Car;
import com.journaldev.design.decorator.LuxuryCar;
import com.journaldev.design.decorator.SportsCar;
public class DecoratorPatternTest {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n*****");
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
}
}
Observe que o programa cliente pode criar diferentes tipos de objetos em tempo de execução e também pode especificar a ordem de execução. A saída do programa de teste acima é:
Basic Car. Adding features of Sports Car.
*****
Basic Car. Adding features of Luxury Car. Adding features of Sports Car.
Padrão de Projeto Decorator – Pontos Importantes
- O padrão de projeto decorator é útil para fornecer habilidades de modificação em tempo de execução e, portanto, mais flexibilidade. É fácil de manter e estender quando o número de escolhas é maior.
- A desvantagem do padrão de projeto decorator é que ele usa muitos objetos semelhantes (decoradores).
- O padrão de decorador é muito usado em classes de Java IO, como FileReader, BufferedReader etc.
Source:
https://www.digitalocean.com/community/tutorials/decorator-design-pattern-in-java-example