Va bene usare il pattern Visitor per le query?

3

In rete e nei libri generalmente vedi esempi del modello di visitatore usando solo "comandi", cioè i metodi eseguono un'azione e non hanno un tipo di ritorno.

È corretto usare questo modello anche per una funzione di interrogazione? Prendiamo ad esempio questa interfaccia Visitor che ottiene la descrizione dello stato dall'oggetto Stato specificato ...

public interface IVisitor
{
    string GetDefaultStatusDescription(DefaultStatus status);
    string GetNewStatusDescription(NewStatus status);
    string GetAciveStatusDescription(AciveStatus status);
    string GetDeactivatedStatusDescription(DeactivatedStatus status);
}

AGGIORNATO IVisitor basato sul commento @JacquesB.

public interface IVisitor
{
    string GetStatusDescription(DefaultStatus status);
    string GetStatusDescription(NewStatus status);
    string GetStatusDescription(AciveStatus status);
    string GetStatusDescription(DeactivatedStatus status);
}
    
posta Dib 21.02.2017 - 15:44
fonte

1 risposta

2

Il pattern visitatore non deve rappresentare comandi. Il fatto che la maggior parte degli esempi del modello di visitatore non abbia un tipo di ritorno è interamente una restrizione del sistema di tipo C ++ e non una parte integrante del modello. Nelle lingue senza un sistema di tipo statico (come Perl, Python, JS, Ruby) o con generici basati sulla cancellazione del tipo (come Java, C #) possiamo definire un oggetto visitabile generico come:

// Java, but C# works similarly

interface Visitable {
  <T> T accept(Visitor<? extends T> visitor);
}

interface Visitor<T> {
  T visitA(A a);
  T visitB(B a);
}

class A implements Visitable {
  @Override
  public <T> T accept(Visitor<? extends T> visitor) {
    return visitor.visitA(this);
  }
}

class B implements Visitable {
  @Override
  public <T> T accept(Visitor<? extends T> visitor) {
    return visitor.visitB(this);
  }
}

...

Queste classi Visitable ora possono accettare qualsiasi visitatore, incluse Visitor<String> , Visitor<Integer> o anche Visitor<Void> istanze.

Come esempio non generico di questo, il tuo IVisitor è assolutamente accettabile. Ti incoraggerei comunque a rendere generico il tuo visitatore in modo che possa essere utilizzato anche per altre operazioni, non solo per ottenere una descrizione dello stato.

Se si dispone di un'interfaccia per visitatori a scopo singolo, ciò indica che la funzionalità fornita dal visitatore potrebbe risiedere negli oggetti di destinazione. Quindi invece di

var description = status.Accept(new StatusDescriptionVisitor());

potremmo dire più direttamente

var description = status.StatusDescription();

La differenza principale è che rendere visibile una gerarchia di classi ci consente di estendere la gerarchia delle classi con nuovi metodi. Ciò è necessario quando non possiamo prevedere tutte le operazioni necessarie o quando le operazioni fanno parte di responsabilità diverse. Tuttavia, se controlliamo tutti gli utilizzi degli oggetti visitabili e per operazioni abbastanza piccole come un getter, forse un metodo semplice è meglio dell'introduzione di un visitatore.

    
risposta data 21.02.2017 - 16:43
fonte

Leggi altre domande sui tag