#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.

May 6, 2025 - 19:27
 0
#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.

Sem Decorator

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.

Image description

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.