Analisador parecido com o SAX: como este padrão é chamado?

5

Eu escrevi um analisador para um determinado tipo de arquivo binário com estrutura recursiva. Eu fiz sua API para ser semelhante ao SAX, ou seja:

  • o analisador aceita um objeto de uma interface específica,
  • essa interface tem vários métodos chamados à medida que a análise acontece: startFoo(type, name) , endFoo() , datum(type, name, value) , badEntry(errorMsg) , etc.
  • há certas promessas sobre como esses retornos de chamada são chamados: por exemplo, para cada startFoo , haverá um endFoo , com aninhamento apropriado, etc.

Eu costumava pensar que isso é uma variante de um padrão de visitante. No entanto, o padrão de visitante não tem vários retornos de chamada, esses retornos têm argumentos diferentes e o padrão Visitante não fala sobre promessas como no último ponto. Além disso, estritamente falando, não é uma estrutura de dados na memória sendo iterada, mas eu acho que essa parte é menos importante…

Eu também acho que não é estritamente um padrão Observer: não há estado para observar; nenhum registro tardio para receber eventos (ou você recebe todos os eventos de análise ou nenhum, você não pode começar no meio); apenas um único objeto é aceito.

Existe um nome mais adequado para esse padrão de design?

EDIT: Pelo que entendi, existem padrões de design para comunicar de forma rápida e precisa as estruturas comuns de código. No entanto, se tudo o que posso dizer sobre a estrutura de código acima é que ela é um padrão "Estratégia" ou um padrão "Observador", a comunicação é ineficiente. Nem todas as implementações do padrão "Estratégia" têm interfaces com vários métodos com promessas relacionadas à ordem em que são chamadas, etc.

Estou procurando um nome ou uma frase que comunique diretamente o conjunto de condições mencionadas acima, ou pelo menos uma aproximação aproximada delas.

    
por liori 17.01.2017 / 00:40
fonte

2 respostas

3

Este é um exemplo do Padrão de Estratégia . A biblioteca fornece um analisador genérico que chama de volta à estratégia de análise fornecida pelo usuário, que permite que o analisador evite manter o estado desnecessário. As garantias adicionais relativas à sequência de invocações de método são apenas uma parte da interface que não pode ser expressa dentro do sistema de tipos como uma assinatura de método.

A intenção do padrão de estado é diferente: Permitir que um objeto mude seu comportamento quando seu estado mudar, sem condicionais excessivos. Para esse fim, cada estado é representado por uma subclasse separada. Um wrapper contém o objeto de estado atual e pode alterar o estado. Aqui, a API do analisador não tem a capacidade de alterar os retornos de chamada. No entanto, a estratégia de suprimentos pode usar o padrão de estado internamente.

A intenção do padrão de visitante é diferente: Para adicionar novas operações a uma hierarquia de classes sem alterar essas classes. O recurso de definição é uma abordagem de expedição dupla que equivale a uma baixa segura. Aqui, parece não haver uma hierarquia de classes que exija um visitante. No entanto, o analisador ou a estratégia pode usar um visitante internamente para lidar com elementos diferentes (por exemplo, para reagir de maneira diferente aos nós de texto, elemento e comentário).

Isso está relacionado ao padrão observador , já que a estratégia de análise é notificada sempre que o estado do analisador é alterado. Como parece não haver suporte para registrar observadores múltiplos , acho que a caracterização como um exemplo do padrão de estratégia é mais precisa. No entanto, essa análise baseada em retorno de chamada que você está vendo é absolutamente um tipo de análise orientada por eventos.

    
por 17.01.2017 / 12:46
fonte
1

Qualquer analisador implementa de alguma forma uma grande máquina de estados onde os estados dependem da gramática da linguagem analisada e da leitura do token léxico, e onde o estado do acionador de entrada muda.

Isso não significa que o analisador use um padrão de design de estado. Você pode implementar analisadores usando construtor, fábrica e outros padrões. Ou nenhum padrão.

Curiosamente, seu objeto receptor também implementa uma máquina de estado: ela oferece uma interface e você espera que suas funções sejam chamadas pelo analisador dependendo de seu estado (por exemplo, End() after start() ). E a maioria das chamadas provocaria algumas mudanças de estado.

Os retornos de chamada de alguma forma ajudam o objeto a replicar os estados do seu analisador, que encaminha os eventos de mudança de estado.

Portanto, em um nível de macro e com base na intenção, você implementa um padrão de observador; Mesmo que a interface de atualização do seu observador seja mais complexa do que a tradicional update() .

    
por 17.01.2017 / 08:54
fonte