# Padrões de Projeto: Decorator
Neste post, vamos explorar o padrão de projeto Decorator, que é um padrão estrutural que permite adicionar novos comportamentos a objetos existentes sem alterar sua classe. O padrão Decorator usa o conceito de composição para envolver um objeto com outro objeto que implementa a mesma interface e delega as chamadas de método para o objeto original, adicionando alguma funcionalidade extra antes ou depois da delegação. Vamos ver um exemplo de código em Java que ilustra como usar o padrão Decorator.
Suponha que temos uma interface Componente que define um método operação. Temos também uma classe ConcretoComponente que implementa essa interface e fornece uma implementação simples do método operação.
```java
public interface Componente {
void operacao();
}
public class ConcretoComponente implements Componente {
@Override
public void operacao() {
System.out.println("Operação do componente concreto");
}
}
```
Agora, queremos adicionar alguns comportamentos extras ao componente concreto, mas sem alterar sua classe ou criar subclasses. Para isso, podemos usar o padrão Decorator. Primeiro, criamos uma classe abstrata Decorador que também implementa a interface Componente e tem um campo protegido que armazena uma referência ao objeto componente que será decorado. No construtor da classe Decorador, passamos o objeto componente como um parâmetro e atribuímos ao campo. No método operação, simplesmente delegamos a chamada ao objeto componente.
```java
public abstract class Decorador implements Componente {
protected Componente componente;
public Decorador(Componente componente) {
this.componente = componente;
}
public void operacao() {
componente.operacao();
}
}
```
Em seguida, podemos criar classes concretas de decoradores que estendem a classe abstrata Decorador e adicionam algum comportamento extra ao método operação. Por exemplo, podemos ter um decorador que adiciona uma borda ao componente e outro que adiciona um texto ao componente.
```java
public class DecoradorBorda extends Decorador {
public DecoradorBorda(Componente componente) {
super(componente);
}
@Override
public void operacao() {
System.out.println("Adicionando borda");
super.operacao();
}
}
public class DecoradorTexto extends Decorador {
public DecoradorTexto(Componente componente) {
super(componente);
}
@Override
public void operacao() {
System.out.println("Adicionando texto");
super.operacao();
}
}
```
Agora, podemos usar esses decoradores para criar objetos componentes com comportamentos diferentes em tempo de execução. Por exemplo, podemos criar um objeto componente simples e decorá-lo com uma borda e um texto.
```java
Componente c = new ConcretoComponente();
c = new DecoradorBorda(c);
c = new DecoradorTexto(c);
c.operacao();
```
A saída desse código seria:
```
Adicionando borda
Adicionando texto
Operação do componente concreto
```
Podemos ver que o padrão Decorator nos permite adicionar novos comportamentos a objetos existentes sem alterar sua classe ou criar subclasses. Isso torna o código mais flexível e extensível. Além disso, o padrão Decorator segue o princípio aberto-fechado, pois permite estender a funcionalidade de um objeto sem modificar seu código fonte.
{"metaMigratedAt":"2023-06-18T00:35:56.986Z","metaMigratedFrom":"Content","title":"Padrões de Projeto: Decorator","breaks":true,"contributors":"[{\"id\":\"9c87567e-43d9-4e74-b77c-0b88ca10e805\",\"add\":3309,\"del\":0}]"}