Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Forma alternativa de implementar a impressão

Olá! Pensei em uma outra forma de implementar o método de impressão. No lugar de criar um método para cada tipo de expressão ('visitaSoma', 'visitaSubtracao', etc), deixei o símbolo dentro da sua respectiva classe e na 'Impressora' criei apenas um método genérico, que atende a todos os tipos de expressão:

interface Visitor {
        public function visitaNumero( Numero $numero );

        public function visitaExpressao( Expressao $exp );
    }
class ImpressoraVisitor implements Visitor {
        public function visitaNumero( Numero $numero ) {
            echo $numero->retornaNumero();
        }

        public function visitaExpressao( Expressao $exp ) {
            echo "(";
            $exp->retornaLadoEsq()->aceita( $this );
            echo $exp->retornaSimbolo();
            $exp->retornaLadoDir()->aceita( $this );
            echo ")";
        }
    }
class Soma implements Expressao {
        private $ladoEsquerdo;
        private $ladoDireito;
        private $simbolo;

        function __construct( Expressao $novoLadoEsq, Expressao $novoLadoDir ) {
            $this->ladoEsquerdo = $novoLadoEsq;
            $this->ladoDireito = $novoLadoDir;
            $this->simbolo = " + ";
        }

        public function retornaLadoEsq() {
            return $this->ladoEsquerdo;
        }

        public function retornaLadoDir() {
            return $this->ladoDireito;
        }

        public function retornaSimbolo() {
            return $this->simbolo;
        }

        public function avalia() {
            $valorEsquerdo = $this->ladoEsquerdo->avalia();
            $valorDireito = $this->ladoDireito->avalia();

            return $valorEsquerdo + $valorDireito;
        }

        public function aceita( Visitor $visitor ) {
            $visitor->visitaExpressao( $this );
        }
    }
//    E1: (1 + 3) + (3 + 5) = 12
    $ladoEsq = new Soma( new Numero( 1 ), new Numero( 3 ) ) ;
    $ladoDir = new Soma( new Numero( 3 ), new Numero( 5 ) );

    $conta = new Soma( $ladoEsq, $ladoDir );
    $impressora = new ImpressoraVisitor();

    $conta->aceita( $impressora );
    echo " = " . $conta->avalia();
    echo "<br/>";

//    E2: (1 + 3) + (5 - 3) = 6
    $ladoEsq = new Soma( new Numero( 1 ), new Numero( 3 ) ) ;
    $ladoDir = new Subtracao( new Numero( 5 ), new Numero( 3 ) );

    $conta = new Soma( $ladoEsq, $ladoDir );
    $impressora = new ImpressoraVisitor();

    $conta->aceita( $impressora );
    echo " = " . $conta->avalia();
    echo "<br/>";

//    E3: (4 * 3) - (12 / 3) = 8
    $ladoEsq = new Multiplicacao( new Numero( 4 ), new Numero( 3 ) ) ;
    $ladoDir = new Divisao( new Numero( 12 ), new Numero( 3 ) );

    $conta = new Subtracao( $ladoEsq, $ladoDir );
    $impressora = new ImpressoraVisitor();

    $conta->aceita( $impressora );
    echo " = " . $conta->avalia();
    echo "<br/>";

Funcionou da mesma forma que o código sugerido na aula. Gostaria de saber se é pertinente utilizar esta forma ou não?

Obrigado!

2 respostas
solução!

Oi Breno, tudo bom?

Acredito que em relação ao pattern visitor não tem impacto. É uma outra abordagem de implementação, aparentemente =)

Perdão pela demora no retorno.

Abraço!

Entendido, André!

Sem problema pela demora. Agradeço pela atenção!