DEV Community

Bruno
Bruno

Posted on

#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
    }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)