Percebi que a classe de implementação do visitor tende a crescer infinitamente pois está ligado diretamente a quantidade de implementações das Expressões. Para diminuir isso pensei em criar uma interface que praticamente todas as Expressões tinham em comum e fiz cada uma delas implementar essa nova interface. É uma boa para diminuir o acoplamento e fazer com que o visitor não cresça tanto?
package br.com.schimidtsolutions.estudo.visitor;
public class ImpressoraPadraoVisitor implements Visitor {
@Override
public void visitar(final Numero numero) {
System.out.print(numero.avaliar());
}
@Override
public void visitar(final OperacaoAritmetica operacaoAritmetica) {
System.out.print("(");
operacaoAritmetica.getNumeroEsquerda().aceitar(this);
System.out.print(operacaoAritmetica.getOperacao());
operacaoAritmetica.getNumeroDireita().aceitar(this);
System.out.print(")");
}
@Override
public void visitar(final RaizQuadrada raizQuadrada) {
System.out.print("²√");
raizQuadrada.getNumero().aceitar(this);
}
}
package br.com.schimidtsolutions.estudo.visitor;
public interface OperacaoAritmetica extends Expressao {
Expressao getNumeroDireita();
Expressao getNumeroEsquerda();
String getOperacao();
}
package br.com.schimidtsolutions.estudo.visitor;
public class Soma implements OperacaoAritmetica {
private final Expressao numeroEsquerda;
private final Expressao numeroDireita;
public Soma(final Expressao expressaoAEsquerda, final Expressao expressaoADireita) {
numeroEsquerda = expressaoAEsquerda;
numeroDireita = expressaoADireita;
}
@Override
public int avaliar() {
return numeroEsquerda.avaliar() + numeroDireita.avaliar();
}
@Override
public Expressao getNumeroDireita() {
return numeroDireita;
}
@Override
public Expressao getNumeroEsquerda() {
return numeroEsquerda;
}
@Override
public void aceitar(final Visitor visitor) {
visitor.visitar(this);
}
@Override
public String getOperacao() {
return "+";
}
}