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!