Muitos sistemas têm uma estrutura com vários tipos de objetos e precisam executar novas operações sobre ela com frequência.
O desafio é adicionar esses comportamentos sem inflar as classes do domínio a cada novo requisito.
if
instanceof
aceitar(visitor)
elemento.aceitar(visitor)
visitor.visitarTexto(this)
ExportadorHtmlVisitor
interface Visitor { void visitarTexto(Texto texto); void visitarTabela(Tabela tabela); } interface ElementoRelatorio { void aceitar(Visitor visitor); }
class Texto implements ElementoRelatorio { @Override public void aceitar(Visitor visitor) { visitor.visitarTexto(this); } } class Tabela implements ElementoRelatorio { @Override public void aceitar(Visitor visitor) { visitor.visitarTabela(this); } }
class ExportadorMarkdownVisitor implements Visitor { @Override public void visitarTexto(Texto texto) { System.out.println(texto.getConteudo()); } @Override public void visitarTabela(Tabela tabela) { System.out.println("## Tabela: " + tabela.getTitulo()); } }