Creazione automatica di oggetti dall'input dell'utente

3

Sto lavorando a un'applicazione della riga di comando che esegue simulazioni. Deve essere molto configurabile; l'utente dovrebbe essere in grado di fornire un numero molto grande (100+) di parametri, alcuni obbligatori e alcuni facoltativi. Ovviamente, questi parametri saranno usati da una varietà di classi nell'applicazione.

Posso vedere due approcci che posso usare; qual è il design migliore a lungo termine?

Approccio 1

Il file di input (testo) controlla direttamente la creazione dell'oggetto nell'applicazione. Ad esempio, l'utente fornirebbe il seguente input:

root=Simulation
  time=50
  local_species=Sentient
    strength=3.5
    intelligence=7.1
  invading_species=Primitive
    strength=5.1
    sociability=2.6

L'applicazione quindi crea in modo ricorsivo oggetti della classe specificata sul rhs del segno di uguale, passando il costruttore della classe gli argomenti forniti nel sotto-ramo pertinente del file di input, se presente. Sto usando Python, che supporta argomenti di parole chiave e valori di argomenti predefiniti quando non viene fornito alcun argomento, ma spero che la domanda non sia terribilmente specifica per la lingua.

Ad esempio, la riga 1 dovrebbe dire all'app di creare un oggetto di class Simulation , con tre argomenti del costruttore. Il primo argomento del costruttore è time=50 . Il secondo argomento è un'istanza di class Sentient , che viene creata passando gli argomenti del costruttore di Simulation strength=3.5 , intelligence=7.1 . Il terzo argomento è un'istanza di class Primitive , che viene creata con il passaggio degli argomenti del costruttore strength=5.1 , sociability=2.6 .

L'intera creazione dell'oggetto viene gestita automaticamente, con poche righe di codice (ricorsivo). L'oggetto di livello più alto (istanza di Simulation in questo caso) verrebbe passato al livello di visualizzazione.

Approccio 2

Il file di input sembra sempre lo stesso. Tuttavia, le classi dell'applicazione ora hanno il controllo completo sul modo in cui interpretano l'input dell'utente. I valori lhs e rhs possono corrispondere o meno ai parametri e alle classi di parole chiave. Ad esempio, l'input sopra riportato può causare l'applicazione che crea un'istanza di class InvasionSimulation con argomenti strength_local=3.5 , intelligence_local=7.1 , strength_invading=5.1 , sociability_invading=2.6 , quindi chiama il metodo set_runtime(time=50) , prima di passare l'oggetto a il livello di visualizzazione.

Un ovvio vantaggio dell'approccio 2 è che l'input dell'utente può rimanere stabile anche se l'applicazione è completamente ridisegnata internamente. Ma penso che non ci sia nulla di sbagliato nel designare un sottoinsieme di classi come "public API", e quindi assicurandoci che non cambi in futuro, vero?

D'altra parte, se l'applicazione segue internamente qualcosa del tutto simile all'approccio 1, comunque, l'approccio 2 richiede l'aggiunta di molto codice ridondante: invece di interpretare automaticamente l'input dell'utente, ora dobbiamo farlo "a mano" "per ogni classe.

Altre considerazioni aggiuntive sarebbero molto apprezzate. Ci sono dei nomi per questi approcci che posso cercare?

    
posta max 22.01.2013 - 05:17
fonte

2 risposte

1

Userei qualcosa come JAXB (in java e con configurazione xml), o qualche JSON mapper (con configurazione JSON) (non mi piacciono le lingue in cui il numero di spazi bianchi è significativo, ma questo è il gusto personale). O qualche altro mapper per il tuo formato preferito / forzato.

Con questo, vorrei usare oggetti mappati se corrispondono a quello che mi serve all'interno dell'applicazione (approccio 1), e se non li userò come parametro per i metodi factory (simile all'approccio 2), quindi il formato della loro sorgente testuale non importa, solo il loro contenuto durante il caricamento. Ciò consentirebbe di utilizzare più formati di input senza modificare nient'altro che la lettura di quei file.

Vorrei iniziare con l'approccio 1 se sembra più promettente e futuro.

    
risposta data 22.01.2013 - 10:06
fonte
0

Nella mia esperienza personale, l'unico approccio migliore per estrarre gli argomenti di comando o di configurazione in un programma a riga di comando è un dizionario. L'input è naturalmente strutturato come coppie chiave-valore, quindi ha senso da un punto di vista input, ma il bonus è manutenibilità quando si devono semplicemente aggiungere nuovi gestori di chiavi e mai un nuovo codice di analisi come il parser semplicemente trascina tutto in un dizionario permettendo qualsiasi tasto necessario. Inoltre non impone lo scoping sul consumatore dello spazio degli argomenti, quindi ogni argomento e valore è disponibile di default a qualsiasi consumatore che lo ritenga pertinente, non è necessario eseguire il lavoro sulle gambe per pubblicizzare l'argomento e il valore per i consumatori.

Inoltre, ho avuto l'abitudine di creare all'inizio un dizionario disponibile per main che ha un elenco di chiavi che corrispondono agli argomenti, e un elenco di valori che sono funzioni per analizzare e gestire le suddette chiavi nella misura in cui tali chiavi richiede la configurazione dello stato del sistema prima che l'elaborazione avvenga. Ad esempio, una chiave di v può avere una funzione che analizza il valore di quella chiave di argomenti nell'impostazione System.Verbosity = true; e l'argomento parser chiama appena _startupDictionary[argument](value); e se la funzione restituisce false che significa che l'argomento non era valido o aveva un argomento non valido , in questo modo può notificare all'argomento parser che lo stato del sistema sarà incoerente dato l'insieme di argomenti disponibili e non può quindi elaborare correttamente.

    
risposta data 22.01.2013 - 06:59
fonte