Padrão de Projeto Visitante com Exemplo em Java

Conceito

O padrão Visitante é um padrão de projeto comportamental que permite definir operações em uma estrutura de objetos sem alterar as classes dos elementos. Ele desacopla as operações da estrutura de dados, facilitando a adição de novos comportamentos quando a estrutura é estável, mas as operações precisam evoluir.

Este padrão concentra operações em objetos visitantes, tornando mais simples adicionar novas funcionalidades. É particularmente útil em sistemas onde a hierarquia de classes é fixa, mas as ações aplicadas a elas variam frequentemente.

Implementação em Java

Abaixo, um exemplo do padrão Visitante em Java, utilizando uma estrutura de arquivos como base. Os visitantes realizam operações como impressão ou salvamento nos diferentes tipos de arquivos.


// Classe abstrata para elementos da estrutura
public abstract class Documento {
    public abstract void aceitar(OperacaoVisitor visitante);
}


// Implementação concreta para documentos de texto
public class DocumentoTexto extends Documento {
    @Override
    public void aceitar(OperacaoVisitor visitante) {
        visitante.processarDocumentoTexto(this);
    }
}


// Implementação concreta para documentos de imagem
public class DocumentoImagem extends Documento {
    @Override
    public void aceitar(OperacaoVisitor visitante) {
        visitante.processarDocumentoImagem(this);
    }
}


// Interface do visitante com métodos para cada tipo de elemento
public interface OperacaoVisitor {
    void processarDocumentoTexto(DocumentoTexto doc);
    void processarDocumentoImagem(DocumentoImagem doc);
}


// Visitante concreto para operação de impressão
public class ImpressoraVisitor implements OperacaoVisitor {
    @Override
    public void processarDocumentoTexto(DocumentoTexto doc) {
        System.out.println("Imprimindo documento texto: " + doc.getClass().getSimpleName());
    }

    @Override
    public void processarDocumentoImagem(DocumentoImagem doc) {
        System.out.println("Imprimindo documento imagem: " + doc.getClass().getSimpleName());
    }
}


// Visitante concreto para operação de salvamento
public class SalvadorVisitor implements OperacaoVisitor {
    @Override
    public void processarDocumentoTexto(DocumentoTexto doc) {
        System.out.println("Salvando documento texto: " + doc.getClass().getSimpleName());
    }

    @Override
    public void processarDocumentoImagem(DocumentoImagem doc) {
        System.out.println("Salvando documento imagem: " + doc.getClass().getSimpleName());
    }
}


// Estrutura que gerencia a coleção de elementos
import java.util.ArrayList;
import java.util.List;

public class ColecaoDocumentos {
    private List<Documento> itens = new ArrayList<>();

    public void inserir(Documento doc) {
        itens.add(doc);
    }

    public void excluir(Documento doc) {
        itens.remove(doc);
    }

    public void aplicarOperacao(OperacaoVisitor visitante) {
        for (Documento elemento : itens) {
            elemento.aceitar(visitante);
        }
    }
}


// Cliente para demonstração do padrão
public class Aplicacao {
    public static void main(String[] args) {
        ImpressoraVisitor impressora = new ImpressoraVisitor();
        SalvadorVisitor salvador = new SalvadorVisitor();

        DocumentoTexto texto = new DocumentoTexto();
        DocumentoImagem imagem = new DocumentoImagem();

        ColecaoDocumentos colecao = new ColecaoDocumentos();
        colecao.inserir(texto);
        colecao.inserir(imagem);

        System.out.println("Operação de impressão:");
        colecao.aplicarOperacao(impressora);

        System.out.println("\nOperação de salvamento:");
        colecao.aplicarOperacao(salvador);
    }
}

Este código ilustra como o padrão Visitante permite adicionar operações como impressão e salvamento sem modificar as classes DocumentoTexto e DocumentoImagem, mantendo a extensibilidade do sistema.

Tags: java DesignPatterns VisitorPattern SoftwareEngineering

Publicado em 7-13 21:00