Visitor Pattern è ancora utile nelle lingue che supportano le estensioni di classe?

4

Il modello di visitatore è utile nelle lingue che supportano le estensioni di classe?

Perché preoccuparsi di implementarlo, quando hai classi aperte o puoi creare una sottoclasse. Se vuoi una nuova funzionalità per una classe, puoi semplicemente creare una sottoclasse, quindi a meno che non mi manchi qualcosa, è ancora (molto) utile nelle lingue che supportano le estensioni di classe?

    
posta Sven 17.01.2014 - 20:29
fonte

4 risposte

3

Il modello visitatore spesso utilizza il modello di doppia spedizione. Quindi per me il modello di visitatore è

double dispatch + structure traversal .

Avrai bisogno della struttura trasversale anche se disponi di perfezionamenti o orientamento del soggetto. Ma la doppia spedizione può assumere altre forme.

    
risposta data 18.01.2014 - 00:02
fonte
3

Sebbene mentre scrivi non sia tecnicamente necessario per implementare la funzionalità di doppia spedizione, è ancora usato. Ad esempio in Pharo Smalltalk (Smalltalk ha un'estensione di classe, sono facili da fare e puoi comprimerli facilmente con la categoria di metodi *Package ) Viene utilizzato il pattern visitatore 3.0 - vedi pacchetto AST-Core .

La ragione di ciò è organizzativa: un visitatore incapsula "modi per gestire questi casi" e per l'uomo che apprende il codice può essere utile averlo in un posto, con nomi familiari.

Se esistessero browser / editor di codice multidimensionali (inseribili per la propria parola d'ordine) basati su AST user-friendly, non ci sarebbe bisogno di modelli Visitor di per sé in queste lingue. Ma sfogliamo ancora il codice in blocchi come pacchetti / classi.

    
risposta data 17.01.2014 - 20:45
fonte
1

Il modello di visitatore non intende estendere la funzionalità di alcune classi. È un pattern che fornisce un modo elegante per operare su alcuni dati (ad esempio per attraversarli) mentre il visitatore può mantenere lo stato e gestire diversi tipi di dati in modo diverso.

Ad esempio, considera uno pseudo-DOM in cui vogliamo raccogliere tutti i titoli, in una lingua con metodi sovraccaricati di tipo:

class CollectHeadlinesVisitor {
  List<String> headlines = new List<>();

  public void visit(Node n) {
    for (Node child in n.childs()) {
      this.visit(child);
    }
  }

  public void visit(Headline h) {
    list.add(h.text());

    for (Node child in n.childs()) {
      this.visit(child);
    }
  }

  public List<String> value() {
    return headlines;
  }
}

Nota che in una lingua senza overload di tipi dobbiamo fare accept / visit_Type indirection.

L'esempio sopra non può essere implementato aggiungendo metodi a Node e Headline come spazio necessario per memorizzare i titoli scoperti.

L'aggiunta di metodi alle classi di dati esistenti violerebbe anche il Principio di Responsabilità Unica e potrebbe portare a problemi nello spazio dei nomi, ad es. quando due pezzi di codice ambozzano entrambi alcuni metodi di visitatore. Alcune lingue risolvono questo problema, ma ciò non significa che sia raccomandabile. La sottoclasse non è un'opzione in quanto vogliamo essere in grado di eseguire un nuovo comportamento sui dati esistenti .

L'utilizzo della corrispondenza del modello come nelle lingue derivate da ML non è un'opzione, in quanto non è estensibile (nel mio esempio potrei sottoclasse il visitatore per gestire anche un altro nodo).

    
risposta data 17.01.2014 - 20:45
fonte
-2

Se dovessi scrivere un compilatore, dovrai usare lo schema del visitatore. Il numero di casi di sottoclasse che dovresti gestire senza renderebbe qualsiasi altro metodo proibitivo, o almeno orribilmente non felice.

    
risposta data 18.01.2014 - 09:38
fonte

Leggi altre domande sui tag