1
resposta

[Dúvida] Dúvida conceitual sobre chain of responsability

Olá, todos bem?

Eu recomecei o curso de Desgin Patterns e me veio um questionamento sobre o tópico de Chain of Responsabilitys.

Quando eu vou encadeando os descontos na classe que calcula os descontos eu meio que não entro no problema de classe infinita? Digo isso porque sempre será necessário alterá-la quando houver a necessidade de uma nova regra de desconto.

1 resposta

Olá, Marcelo! Tudo bem?

A sua dúvida sobre o padrão Chain of Responsibility é muito pertinente. Esse padrão é realmente utilizado para evitar a criação de classes monolíticas e facilitar a adição de novas regras sem modificar as existentes. No entanto, é importante implementá-lo de maneira correta para evitar problemas como o que você mencionou.

No padrão Chain of Responsibility, você cria uma cadeia de objetos, onde cada objeto tem a responsabilidade de processar uma solicitação ou passá-la adiante. Quando você precisa adicionar uma nova regra de desconto, você cria uma nova classe que implementa a interface de desconto e a adiciona à cadeia. Isso evita a necessidade de modificar as classes existentes, promovendo o princípio de aberto/fechado (Open/Closed Principle) do SOLID, que sugere que as classes devem estar abertas para extensão, mas fechadas para modificação.

Por exemplo, imagine que você tem um sistema de descontos onde já existem regras para desconto por quantidade e desconto por fidelidade. Se precisar adicionar um desconto sazonal, você criaria uma nova classe DescontoSazonal que implementa a interface de desconto e a encadearia na sequência existente.

interface Desconto {
    public function calcula(Compra $compra);
}

class DescontoPorQuantidade implements Desconto {
    public function calcula(Compra $compra) {
        // lógica para desconto por quantidade
    }
}

class DescontoPorFidelidade implements Desconto {
    public function calcula(Compra $compra) {
        // lógica para desconto por fidelidade
    }
}

class DescontoSazonal implements Desconto {
    public function calcula(Compra $compra) {
        // lógica para desconto sazonal
    }
}

// Encadeando os descontos
$descontoPorQuantidade = new DescontoPorQuantidade();
$descontoPorFidelidade = new DescontoPorFidelidade();
$descontoSazonal = new DescontoSazonal();

// Configurando a cadeia
$descontoPorQuantidade->setProximo($descontoPorFidelidade);
$descontoPorFidelidade->setProximo($descontoSazonal);

// Calculando o desconto
$descontoPorQuantidade->calcula($compra);

Dessa forma, ao adicionar um novo tipo de desconto, você apenas cria uma nova classe e a adiciona na cadeia, sem alterar as classes já existentes. Isso ajuda a manter o código mais limpo e fácil de manter.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.