#6 DP: Decorator
O que é o Padrão Decorator? O Decorator é um padrão de projeto estrutural que permite adicionar comportamentos adicionais a um objeto de forma dinâmica. Ele permite que você encadeie funcionalidades (como validação, construção, logging e outras) em um fluxo sequencial, sem modificar a estrutura original da classe. Isso possibilita adicionar ou remover comportamentos com facilidade, mantendo o código mais flexível e desacoplado. Em resumo, o Decorator cria uma cadeia de responsabilidades onde cada classe pode adicionar sua funcionalidade à sequência, sem afetar as outras. Exemplo prático Imagina que você precisa realizar várias validações (como validar o usuário, estoque e status), mas não quer que elas fiquem fortemente acopladas. O objetivo é poder adicionar, remover ou reorganizar facilmente as validações sem mexer nas classes existentes. Sem o Decorator: Sem o padrão Decorator, você teria algo assim: Cada validação seria chamada individualmente, uma após a outra, com código acoplado e sem flexibilidade para adicionar ou remover comportamentos sem alterar diretamente o código. public class MyClass { public static void main(String args[]) { Object request = new Object(); ValidaEstoque validaEstoque = new ValidaEstoque(); validaEstoque.valida(request); ValidaUsuario validaUsuario = new ValidaUsuario(); validaUsuario.valida(request); ValidaStatus validaStatus = new ValidaStatus(); validaStatus.valida(request); } } public class ValidaEstoque { public static void valida(Object request) { // lógica de validação de estoque } } public class ValidaUsuario { public static void valida(Object request) { // lógica de validação de usuário } } public class ValidaStatus { public static void valida(Object request) { // lógica de validação de status } } Com o Decorator: Com o padrão Decorator, você pode encadear validações de forma dinâmica, passando o "próximo" validador para o próximo da cadeia. Isso facilita a extensão e a modificação das validações sem mexer no código das classes específicas. Cada "decorador" implementa uma lógica de validação e, ao final, passa a responsabilidade para o próximo validador da cadeia. public class MyClass { public static void main(String[] args) { Object request = new Object(); // Encadeando os validadores Valida validador = new ValidaEstoque( new ValidaUsuario( new ValidaStatus())); validador.valida(request); } } // Interface base para os validadores interface Valida { void valida(Object request); } // Validador abstrato base com lógica comum abstract class BaseValidadorDecorator implements Valida { protected Valida proximo; public BaseValidadorDecorator(Valida proximo) { this.proximo = proximo; } @Override public void valida(Object request) { executarValidacao(request); if (proximo != null) { proximo.valida(request); // Chama o próximo validador } } protected abstract void executarValidacao(Object request); } // Validador de Status (último da cadeia, mas seguro sozinho) class ValidaStatus extends BaseValidadorDecorator { public ValidaStatus() { super(null); // Não há próximo validador } @Override protected void executarValidacao(Object request) { System.out.println("Validando status..."); // Lógica de validação de status } } // Validador de Usuário class ValidaUsuario extends BaseValidadorDecorator { public ValidaUsuario(Valida proximo) { super(proximo); } @Override protected void executarValidacao(Object request) { System.out.println("Validando usuário..."); // Lógica de validação de usuário } } // Validador de Estoque class ValidaEstoque extends BaseValidadorDecorator { public ValidaEstoque(Valida proximo) { super(proximo); } @Override protected void executarValidacao(Object request) { System.out.println("Validando estoque..."); // Lógica de validação de estoque } } Vantagens do Decorator: Flexibilidade: Você pode adicionar ou remover validadores facilmente, sem alterar a estrutura do código. Só precisa instanciar e passar os decoradores na ordem desejada. Desacoplamento: Cada validador é independente e sabe apenas sobre a sua validação e o "próximo", sem depender de implementações específicas. Extensibilidade: Se precisar adicionar mais validações, basta criar uma nova classe que implemente BaseValidadorDecorator e passá-la na cadeia. Melhor manutenção: Como o código é mais modular, fica mais fácil de entender, testar e manter.

O que é o Padrão Decorator?
O Decorator é um padrão de projeto estrutural que permite adicionar comportamentos adicionais a um objeto de forma dinâmica. Ele permite que você encadeie funcionalidades (como validação, construção, logging e outras) em um fluxo sequencial, sem modificar a estrutura original da classe. Isso possibilita adicionar ou remover comportamentos com facilidade, mantendo o código mais flexível e desacoplado.
Em resumo, o Decorator cria uma cadeia de responsabilidades onde cada classe pode adicionar sua funcionalidade à sequência, sem afetar as outras.
Exemplo prático
Imagina que você precisa realizar várias validações (como validar o usuário, estoque e status), mas não quer que elas fiquem fortemente acopladas. O objetivo é poder adicionar, remover ou reorganizar facilmente as validações sem mexer nas classes existentes.
Sem o Decorator:
Sem o padrão Decorator, você teria algo assim:
- Cada validação seria chamada individualmente, uma após a outra, com código acoplado e sem flexibilidade para adicionar ou remover comportamentos sem alterar diretamente o código.
public class MyClass {
public static void main(String args[]) {
Object request = new Object();
ValidaEstoque validaEstoque = new ValidaEstoque();
validaEstoque.valida(request);
ValidaUsuario validaUsuario = new ValidaUsuario();
validaUsuario.valida(request);
ValidaStatus validaStatus = new ValidaStatus();
validaStatus.valida(request);
}
}
public class ValidaEstoque {
public static void valida(Object request) {
// lógica de validação de estoque
}
}
public class ValidaUsuario {
public static void valida(Object request) {
// lógica de validação de usuário
}
}
public class ValidaStatus {
public static void valida(Object request) {
// lógica de validação de status
}
}
Com o Decorator:
Com o padrão Decorator, você pode encadear validações de forma dinâmica, passando o "próximo" validador para o próximo da cadeia. Isso facilita a extensão e a modificação das validações sem mexer no código das classes específicas.
Cada "decorador" implementa uma lógica de validação e, ao final, passa a responsabilidade para o próximo validador da cadeia.
public class MyClass {
public static void main(String[] args) {
Object request = new Object();
// Encadeando os validadores
Valida validador = new ValidaEstoque(
new ValidaUsuario(
new ValidaStatus()));
validador.valida(request);
}
}
// Interface base para os validadores
interface Valida {
void valida(Object request);
}
// Validador abstrato base com lógica comum
abstract class BaseValidadorDecorator implements Valida {
protected Valida proximo;
public BaseValidadorDecorator(Valida proximo) {
this.proximo = proximo;
}
@Override
public void valida(Object request) {
executarValidacao(request);
if (proximo != null) {
proximo.valida(request); // Chama o próximo validador
}
}
protected abstract void executarValidacao(Object request);
}
// Validador de Status (último da cadeia, mas seguro sozinho)
class ValidaStatus extends BaseValidadorDecorator {
public ValidaStatus() {
super(null); // Não há próximo validador
}
@Override
protected void executarValidacao(Object request) {
System.out.println("Validando status...");
// Lógica de validação de status
}
}
// Validador de Usuário
class ValidaUsuario extends BaseValidadorDecorator {
public ValidaUsuario(Valida proximo) {
super(proximo);
}
@Override
protected void executarValidacao(Object request) {
System.out.println("Validando usuário...");
// Lógica de validação de usuário
}
}
// Validador de Estoque
class ValidaEstoque extends BaseValidadorDecorator {
public ValidaEstoque(Valida proximo) {
super(proximo);
}
@Override
protected void executarValidacao(Object request) {
System.out.println("Validando estoque...");
// Lógica de validação de estoque
}
}
Vantagens do Decorator:
Flexibilidade: Você pode adicionar ou remover validadores facilmente, sem alterar a estrutura do código. Só precisa instanciar e passar os decoradores na ordem desejada.
Desacoplamento: Cada validador é independente e sabe apenas sobre a sua validação e o "próximo", sem depender de implementações específicas.
Extensibilidade: Se precisar adicionar mais validações, basta criar uma nova classe que implemente BaseValidadorDecorator e passá-la na cadeia.
Melhor manutenção: Como o código é mais modular, fica mais fácil de entender, testar e manter.