Pattern per l'interazione dell'utente e la conferma

2

Supponiamo che una classe FileWriter necessiti della convalida che non cancellerà un file già presente, se ne viene trovato uno. Avrebbe due funzioni:

public bool FileExists(string filePath) //...
public bool WriteFile(string filePath, string text) //...

La preoccupazione principale è di non cancellare un file già presente. Una prima interfaccia è in realtà solo l'interazione tramite una console:

public void Save()
{
    FileWriter fileWriter;
    //...
    if (fileWriter.FileExists(filePath))
    {
        Console.WriteLine("File already exists. Continue? Press 'y' for yes");
        if (Console.ReadKey().KeyChar != 'y')
            return;
    }
    fileWriter.WriteFile(filePath, text);
}

E qualche tempo dopo arriva una seconda interfaccia, questa con una GUI, che richiede la stessa interazione con l'utente:

public void SaveButton_click(object sender, EventArgs e)
{
    FileWriter fileWriter;
    //...
    if (fileWriter.FileExists(filePath))
    {
        if (DialogResult.Yes != MessageBox.Show("File already exists. Continue?", "", MessageBoxButtons.YesNo))
            return;
    }
    fileWriter.WriteFile(filePath, text);
}

Risparmia il modo in cui viene realizzata l'interazione, la logica è la stessa. Quale modello può essere usato per non duplicare questa logica? È una funzione di callback per eseguire la verifica dell'approccio migliore?

Formattato come C #, ma non deve essere specifico per C #.

    
posta MPelletier 22.12.2011 - 04:18
fonte

2 risposte

1

Non so se è un pattern con un nome, ma questo è un buon modo per risolverlo:

interface IUserInputService
{
  bool AskQuestion( string q );
}

class FileWriterService
{
  public FileWriterService( IUserInputService scv )
  {
    this.svc = svc
  }

  public void WriteFileIfItDoesntExist( string path, string text )
  {
    FileWriter fileWriter;
    if( fileWriter.FileExists( path ) )
      if( !svc.AskQuestion( "File exists, continue?" ) )
        return;
    fileWriter.WriteFile( path, text );
  }
}

quindi fornisci le implementazioni del servizio di input in base a se sei su una console o vuoi una finestra di dialogo / popup /...

    
risposta data 22.12.2011 - 09:02
fonte
3

Se hai una classe di business logic (in questo caso il tuo FileWriter ) che deve far apparire alcune UI (la finestra di dialogo o l'input della console nel tuo caso) uno dovrebbe separare questa UI dalla logica di business. Non l'hai descritto in questi termini, ma penso che la tua domanda vada in quella direzione.

In questo caso, FileWriter esporrà solo l'unico metodo WriteFile() e controllerebbe internamente, indipendentemente dal fatto che il file esista. Se lo fa, chiamerebbe un delegato (ad esempio una richiamata passata nel metodo WriteFile() ) per chiedere il permesso di sovrascriverlo. In questo modo tutta la tua logica aziendale (verifica dell'esistenza dei file, scrittura del file, ecc.) È incapsulata nella classe FileWriter e il codice che chiama dall'interfaccia utente fornisce i mezzi per chiedere conferma.

Se ci sono situazioni aggiuntive in cui FileWriter potrebbe dover richiamare il codice invocandolo, avere delegati individuali per ognuna di queste situazioni potrebbe essere un po 'confuso. Se le situazioni sono tutte molto simili, è possibile fornire ulteriori informazioni su di esse nell'argomento dell'evento al delegato. Oppure l'utente potrebbe passare un'interfaccia (diciamo IConfirmationProvider ) i cui metodi il FileWriter potrebbe chiamare per chiedere conferma in ognuna delle diverse situazioni. Dipende davvero dalla natura esatta delle situazioni in cui è necessario il permesso.

    
risposta data 22.12.2011 - 09:03
fonte

Leggi altre domande sui tag