2
respostas

Chain of Responsibility ou Strategy

Olá pessoal, para o caso específico do exercício proposto seria melhor/mais fácil usar strategy? Consegui fazer das duas formas, mas comparando acho que pra esse caso strategy foi mais direto e precisei escrever bem menos. Algum motivo para preferir correntes nesse caso?

Fazendo com STRATEGY

Index

$hsbc = new Banco("HSBC", "(64) 3411-3212");
$hsbc->setEmail("contato@hsbc.com.br");
$hsbc->setEndereco("Rua da Saudade, 432, Centro, Catalão - Goiás");

$hsbc->setContas(new Conta("Israel Rodrigues", "04323", "432483298-0", 354));
$hsbc->setContas(new Conta("Jaqueline Pascoal", "54323", "53483298-0"));

$relatorio = new DefineRelatorios();
$relatorio->defineRelatorioUsado($hsbc, new RelatorioComplexo());

Onde as estratégias são injetadas

class DefineRelatorios{
    public function defineRelatorioUsado(Banco $banco, IRelatorio $relatorio){
        return $relatorio->retornaRelatorio($banco);
    }
}

Template

abstract class TemplateCabecalho implements IRelatorio {

    public function retornaRelatorio(Banco $banco){
        $this->cabecalho($banco);
        $this->conteudo($banco);
        $this->rodape($banco);
    }

    abstract function cabecalho(Banco $banco);
    abstract function conteudo(Banco $banco);
    abstract function rodape(Banco $banco);
}

Relatório Simples

class RelatorioSimples extends TemplateCabecalho {

    function cabecalho(Banco $banco){
       echo $banco->getNome() . "<br>";;
    }

    function conteudo(Banco $banco){
        foreach ($banco->getContas() as $conta){
            echo $conta->getNome() . " - R$ " . $conta->getSaldo() . "<br>";
        }
    }

    function rodape(Banco $banco){
        echo $banco->getTelefone() . "<br>";;
    }

Fazendo com Chain Index

$hsbc = new Banco("HSBC", "(64) 3411-3212");
$hsbc->setEmail("contato@hsbc.com.br");
$hsbc->setEndereco("Rua da Saudade, 432, Centro, Catalão - Goiás");

$hsbc->setContas(new Conta("Israel Rodrigues", "04323", "432483298-0", 354));
$hsbc->setContas(new Conta("Jaqueline Pascoal", "54323", "53483298-0"));

//$relatorio = new DefineRelatorios();
$relatorio = new CorrenteDeRelatorios();

$relatorio->defineRelatorioUsado($hsbc, Relatorios::$COMPLEXO);

Corrente

class CorrenteDeRelatorios{

    public function defineRelatorioUsado(Banco $banco, $tipoRelatorio){
        $relatorioSimples = new RelatorioSimples();
        $relatorioComplexo = new RelatorioComplexo();

        $relatorioSimples->setProximo($relatorioComplexo);

        $relatorioSimples->retornaRelatorio($banco, $tipoRelatorio);
    }

}

Template

abstract class TemplateCabecalho implements IRelatorio {

    private $proximo;

    public function retornaRelatorio(Banco $banco, $tipoRelatorio){
        if($this->vaiUsarEsse($tipoRelatorio)){
            $this->cabecalho($banco);
            $this->conteudo($banco);
            $this->rodape($banco);
        }else{
            return $this->proximo->retornaRelatorio($banco, $tipoRelatorio);
        }
    }

    public function setProximo(IRelatorio $proximo){
        $this->proximo = $proximo;
    }

    abstract function cabecalho(Banco $banco);
    abstract function conteudo(Banco $banco);
    abstract function rodape(Banco $banco);
    abstract function vaiUsarEsse($tipoRelatorio);
}

Relatorio Simples

class RelatorioSimples extends TemplateCabecalho {

    function cabecalho(Banco $banco){
       echo $banco->getNome() . "<br>";;
    }

    function conteudo(Banco $banco){
        foreach ($banco->getContas() as $conta){
            echo $conta->getNome() . " - R$ " . $conta->getSaldo() . "<br>";
        }
    }

    function rodape(Banco $banco){
        echo $banco->getTelefone() . "<br>";;
    }

    function vaiUsarEsse($relatorio){
        if($relatorio == Relatorios::$SIMPLES) return true;
        else return false;
    }
}
2 respostas

Essa resposta depende do problema que está sendo resolvido e da solução proposta. E ainda assim, é possível que alguns padrões atendam sua necessidade.

Agora, os dois padrões discutidos possuem características distintas, onde o Strategy prevê a definição de alguns comportamentos possíveis para um processo, e o comportamento adequado é definido em runtime. Já o Chain of responsability define uma sequencia de processos onde a etapa atual executa o seu sucessor lhe dando os dados necessários, e assim por diante.

Ou seja, os padrões estão ai para nos auxiliar a pensar sobre o problema e como soluciona-lo. Não são verdades absolutas. Nesse sentido, o padrão pode ter sido escolhido pelo instrutor para exemplificar, mas a solução que você propôs também pode antender.

Alguma consideração para a resposta?