Come strutturare la lettura dei comandi dati al prompt della CLI (n interattiva)?

1

Diciamo che ho un programma chiamato theprogram (il team di marketing era in sciopero quando il prodotto doveva essere nominato). Comincio quel programma digitando, forse non sorprendentemente, il nome del programma come comando in un prompt dei comandi. Dopodiché, vado in loop (dal punto di vista degli utenti, un prompt della riga di comando interattivo), dove un comando verrà letto dall'utente e, a seconda di quale comando è stato dato, il programma eseguirà alcune istruzioni.

Ho fatto qualcosa di simile al seguente (in pseudocodice C-like):

main_loop{
 in=read_input();
 if(in=="command 1")
  do_something();
 else if(in=="command 2")
  do_something_else();
 ...
}

(In un programma reale, probabilmente incorporo più cose in diverse procedure, questo è solo un esempio.)

Funziona bene per una piccola quantità di comandi, ma diciamo che ne hai 100, 1000 o anche 10.000 (il manuale sarebbe enorme! ). È chiaramente una cattiva idea avere il 10.000% diif se else if s l'uno dopo l'altro, ad esempio, il programma sarebbe difficile da leggere, difficile da mantenere, contenere un sacco di codice standard ... Sì, tu non voglio farlo, quindi quale approccio mi consiglieresti di usare (probabilmente non userò mai 10.000 comandi in un programma, ma la soluzione dovrebbe, almeno preferibilmente, essere in grado di adattarsi a quel tipo di enorme (? ) problemi La soluzione non deve consentire argomenti per i comandi)?

    
posta Anto 16.03.2011 - 20:32
fonte

5 risposte

1

Leggi questo.

link

È un buon design e potrebbe essere adattato alle altre lingue senza troppi problemi.

    
risposta data 16.03.2011 - 20:50
fonte
1

Suggerirei di avere un factory (pattern) che crea il comando (pattern). L'input per la factory sarebbe il nome del comando (e potrebbe essere il resto della riga di comando per le opzioni aggiuntive) e l'output del commandobject da eseguire.

Una potente implementazione di questa combinazione dovrebbe mappare il nomecomando ad un nome di file di un plugin da eseguire.

Git usa questo approc.

Esempio

  • "Git add" esegue il plugin "git-add.exe"
  • "Git tfs" esegue il plugin "git-tfs.exe"
risposta data 17.03.2011 - 06:54
fonte
0

Probabilmente il miglior modo agnostico per farlo è separare la gestione di ogni comando in un file separato, o almeno separare funzioni o metodi. In un modo o nell'altro, è possibile passare un comando immesso alla funzione / metodo specifico per eseguire il lavoro specifico.

In questo modo puoi separare in modo pulito diversi lavori l'uno dall'altro. Mentre all'inizio potrebbe sembrare un sacco di codice e codice, penserai diversamente quando hai centinaia di comandi diversi. La scalabilità è la chiave per questo.

Questo naturalmente richiede che il codice passi l'input alla funzione / metodo corretto. A volte questo è già fatto per te come in python menzionato da @ S.Lott.

    
risposta data 16.03.2011 - 23:04
fonte
0

È possibile creare una struttura dati contenente comandi e puntatori di funzioni a un metodo per gestire tali comandi. La struttura dei dati dipenderà dalle tue esigenze, ma due idee sarebbero una tabella hash (molto veloce) o una struttura i cui identificatori a ciascun livello sono caratteri che compongono il comando.

Ad esempio

 <root>
a      b
pple   a     l
       nnana ue

Qui ho preso una scorciatoia per includere l'intero comando una volta eliminata l'ambiguità.

Ora che hai una configurazione della struttura dati, il tuo processo di runtime consiste semplicemente nel cercare quale comando è stato inserito e passare qualsiasi argomento. Tuttavia, per costruire la struttura dovrai riempirla, sia che tu usi una funzione di registrazione accessibile a livello globale che ogni funzione init di moduli deve chiamare o una funzione gigante (potenzialmente generata automaticamente) per farlo.

    
risposta data 16.03.2011 - 23:32
fonte
0

Ci sono due parti per un'implementazione CLI, l'elaborazione di input e l'interpretazione (o l'esecuzione) dell'input.

Per quanto riguarda l'interpretazione, il modello di progettazione degli interpreti si applica perché è un modo naturale "per strutturare [interpretazione] di comandi su una CLI "al contrario di una gigantesca istruzione if / else o switch.

In alternativa, il modello di progettazione Command è un'opzione che può essere utilizzata da sola o accoppiato con Interpreter (così come con il pattern Chain of Responsibility).

Non sembrare un drogato GOF, ma i modelli di design possono, a volte, fornire soluzioni eleganti a problemi privi di soluzioni "ovvie". Per quanto riguarda la lettura e la conversione dell'input stesso (al contrario dell'interpretazione dei comandi), il modello Factory suggerito di seguito è un'idea eccellente. Questa risposta non è teorica come ho visto / lavorato sulle implementazioni della CLI sulla base dei modelli suggeriti, ed erano abbastanza efficaci.

    
risposta data 17.03.2011 - 00:10
fonte

Leggi altre domande sui tag