Come passare i parametri della riga di comando in varie parti del programma

2

Considera un programma di grandi dimensioni con molte parti differenti che hanno un'unica interfaccia a riga di comando, come nel caso della maggior parte delle applicazioni. Quanto meglio gestire i vari parametri della riga di comando, che possono essere intesi per varie parti dell'applicazione, a loro?

Queste parti possono essere gerarchiche, ad esempio main() istanzia A (che crea un'istanza di B, C) e D (che genera E) e ognuna di esse ha requisiti specifici per i parametri della riga di comando. Ci sono varie possibilità.

  • Crea variabili globali per i parametri, impostale e poi leggi semplicemente come richiesto. Forse in uno spazio dei nomi di configurazione o in una classe o qualche tipo.
  • Crea una HashMap, che mappa gli argomenti della riga di comando, che costituiscono membri di un Enum, ai loro valori. Queste sono inizialmente delle stringhe, ma ogni parte del programma legge e interpreta i tipi come richiesto. Questa mappa è passata gerarchicamente con ogni istanza.
  • Crea classi per AConf, DConf, che vengono poi compilate da main e passate a A e D resp., da cui creano BConf, CConf, EConf e passano tali oggetti di configurazione a B, C, E resp.

e molti altri.

In una grande applicazione con varie parti, come viene gestita con garbo?

Nota: sono non che mi chiede informazioni sull'analisi degli argomenti. Sto chiedendo come inviare i valori a oggetti diversi dopo che sono stati analizzati.

    
posta forumulator 12.07.2018 - 18:19
fonte

5 risposte

4

Per questo è OK avere una classe statica in una libreria condivisa che ottiene l'intera linea di comando all'avvio. Supponi di chiamarlo CommandLine. È quindi possibile creare metodi come

bool HasSwitch(string)

e

string GetNamedArgument(string)

su di esso. Se hai bisogno di un parsing più sofisticato in seguito, puoi facilmente aggiungerlo.

    
risposta data 12.07.2018 - 19:03
fonte
2

Nelle applicazioni complesse, vedo i parametri della riga di comando come la fonte di massima priorità della configurazione dell'applicazione, quindi includo la loro gestione nella stessa logica delle informazioni di configurazione.

Nel mio senso, le informazioni di configurazione vengono recuperate da (priorità più alta prima):

  • argomenti della riga di comando
  • file di configurazione fornito negli argomenti della riga di comando
  • variabili d'ambiente
  • file di configurazione definito dall'utente (ad esempio ~/.myapprc su Unix)
  • file di configurazione globale (ad esempio /etc/myapprc su Unix)
  • configurazione predefinita definita in fase di compilazione
risposta data 16.07.2018 - 12:14
fonte
1

In a large application with various parts, how is this handled gracefully?

Qualunque soluzione suggerita potrebbe funzionare, ma con l'aumentare delle dimensioni e della portata del progetto, ogni metodo ha la sua rovina. In definitiva penso che questo sia meglio risolto con una configurazione singleton , che può supportare qualsiasi cosa, da una hashmap a una getConfigA (... ) o qualsiasi altra soluzione specifica che desideri.

Equivalentemente una funzione statica o un insieme di funzioni statiche può avere lo stesso scopo; se hai bisogno di qualcosa che sente / odora di globale, un singleton è probabilmente una soluzione migliore.

    
risposta data 13.07.2018 - 00:05
fonte
0

Paradigma Parametri-Modello-Vista-Controller

Nella stessa situazione: molti casi d'uso, casi d'uso in un menu di navigazione, parametri per i casi d'uso (selezione di alcune categorie, selezione di articoli d'ordine, ...).

Avevamo una classica classe UseCase<Model, View, Controller> , ma ora abbiamo un

UseCase<P, M, V, C>
UseCase<Parameters, Model, View, Controller>

Quindi dividiamo il modello classico in:

  • M (mutabile) modello di dati e
  • P (parametrazione fissa, variabili di controllo / costanti, dati di intestazione)

In effetti i parametri hanno una durata diversa da Model.

Questo significa che ogni caso d'uso XxxUseCase ha la sua classe XxxParameters. Si potrebbe benissimo argomentare per un qualche tipo di approccio scripting / dichiarativo; come menzione delle mappe di hash. Ma se non ce n'è bisogno, un riferimento da un componente di sistema ad un altro è meglio servito da una classe di parametri specificata, sicura del parametro. Specialmente se il numero e la variazione dei parametri crescono.

    
risposta data 16.07.2018 - 15:58
fonte
-2

Solitamente (salvo alcuni requisiti molto specifici) nessuna delle tre opzioni suggerite è sufficiente, né l'oggetto statico. Tutti hanno gli stessi problemi: gli oggetti sono tenuti a conoscere gli argomenti della riga di comando e il fallimento dell'incapsulamento della conoscenza.

Il problema inizia con questa frase:

main() instantiates A (which instantiates B, C) and D (which spawns E)

Questo non è esattamente il modo in cui un programma orientato agli oggetti dovrebbe funzionare. Tutti del programma dovrebbero essere collegati insieme nella parte superiore della gerarchia di esecuzione, ad esempio nel metodo main() . Molto raramente gli oggetti si istanziano direttamente l'un l'altro, se non del tutto. Utilizziamo inversione di dipendenza , fabbriche e altre cose per assicurarci di poter separare l'istanziazione e l'utilizzo degli oggetti.

Se lo fai, in realtà creerai un'istanza per le cose che contano nel tuo main() , il che significa che puoi direttamente configurarle con valori significativi (come un periodo di timeout come Durata) invece di solo un sacco di stringhe senza significato a tutti.

    
risposta data 16.07.2018 - 11:27
fonte