Struttura di classe / modello per la convalida di diversi modelli di Excel diversi?

1

Sto provando a convalidare il contenuto dei fogli Excel che seguono diversi modelli. Per ognuna, ci sono tre possibili azioni di convalida per varie celle:

  • Regex (ad es. "XYZ-123" fallisce perché non si adatta al modello "[A-Z] {4} - \ d {3}")
  • Il formato data / ora (ad es. "gen 24, 2013" non riesce perché non è mm / gg / aaaa)
  • Tipo di dati (ad es. "xyz" fallisce perché non è un intero)

Il mio primo pensiero è stato quello di utilizzare la seguente classe:

public class Validator
{
 Excel.Worksheet vSheet;
 List<Tuple<string,string,string>> cellActions=new List<Tuple<string,string,string>>();

 //populates the list of cellActions based on the template type
 public Validator(Excel.Worksheet sht)
 {
  this.vSheet=sht;
  string templateType=templateCheck(sht);
  switch (templateType)
  {
   case "type1":
    cellActions.Add(new Tuple<string,string,string>("C5","regex","[A-Z\d]{6}");
    cellActions.Add(new Tuple<string,string,string>("D3","datatype","long");
    //and so on for another 30 list items
    break;
   case "type2"
    cellActions.Add(new Tuple<string,string,string>("A3","date_time","yyyy-MM-dd HH:mm");
    cellActions.Add(new Tuple<string,string,string>("A6","regex",".+\s[ACGT]{3}");
    //etc.
  }
 }

 private string templateCheck(Excel.Worksheet sht)
 {
  //return template type as string based on contents of worksheet
 }

 public void validate()
 {
  foreach(Tuple<string,string,string> cellAction in cellActions)
  {
   //check the contents of the cell in the vSheet property according to cellAction's rules
  }
 }
}

}

Questo è un caso in cui il modello di strategia sarebbe appropriato? Esistono diversi tipi di fogli, ognuno con un diverso elenco di celle e regole per quelle celle, quindi forse sarebbe giusto pensare a ogni modello come strategia da implementare come classe. Oppure non si tratta di una situazione in cui si applica il modello, dato che ciascuno dei 3 tipi di azioni di convalida è sempre lo stesso indipendentemente dal modello in cui è applicato?

    
posta sigil 24.01.2013 - 21:54
fonte

2 risposte

0

Pensa a quale problema stai cercando di risolvere e dove potrebbe cambiare. Se si tratta di utilizzare Excel per consentire agli utenti di inviare dati, è necessario prendere in considerazione l'associazione dati XML e un XSD. (O, almeno, le regole incorporate di Excel per la convalida.)

Per la domanda specifica, no, non credo che un modello di strategia sia appropriato qui. Stai eseguendo lo stesso compito, solo con un input diverso ogni volta, e con un legame troppo stretto tra il codice del tuo programma C # e gli standard particolari che si verificano.

Rimuovere le regole standard in un archivio dati di qualche tipo (XML, SQL, file flat, anche un XSL) e caricarle come si farebbe con qualsiasi altro insieme di dati da testare. A meno che tu non stia usando quei valori e strutture dati nel codice, non dovresti vincolarli così strettamente. E con oltre 30 test per tipo di input, odora qualcosa che cambierà più spesso di quanto sospetti.

    
risposta data 28.05.2013 - 06:43
fonte
0

Vorrei andare con una digitazione specifica per le tue cellule. C5 è un ... tipo di cella identificatore? Vai specifico, specifico del tuo dominio.

Quindi, descrivi ogni foglio in termini di quali celle con quali tipi contiene. Incapsala, mettila in una classe che rappresenta il foglio.

Ora hai una bella struttura ad oggetti che rappresenta i tuoi fogli di calcolo Excel consentiti. La convalida viene incapsulata nel tipo per ogni cella. Nota come ottieni il massimo riutilizzo e acquisisci la struttura dei tuoi fogli.

Se si tratta di strategia, le linee sono sfocate, ma sì, considero i validatori così incorporati nei tipi come un'incarnazione del modello di progettazione della strategia.

La validazione ora diventa una semplice questione di passare attraverso ogni foglio e ogni cella di interesse e invocare il validatore sulla cella, che delegherà al validatore del tipo.

class CellType {
    bool IsValid(string value);
    string DisplayName { get; }
}

class Cell {
    string Value { get; set }
    CellType Type { get; set; }
    boolean IsValid() { return Type.IsValid(Value); }
}

class CellPosition {
    ...
}

class Sheet {
    Cell CellAt(CellPosition position);
    IEnumerable<Cell> CellsOfInterest { get; }
}

void Validate() {
    foreach (Sheet sheet in sheets) {
        foreach (Cell cell in sheet.CellsOfInterest) {
            if (!cell.IsValid()) {
                // Whoops!
            }
        }
    }
}

Nota: è eccessivo usare Visitor per convalidare la struttura degenerata "composita" indotta da Sheet e Cell , poiché la struttura ha sempre due strati esattamente come previsto. Per questo motivo, non l'ho menzionato. :)

    
risposta data 28.01.2013 - 02:01
fonte

Leggi altre domande sui tag