2010-03-20 16 views
5

Desidero scrivere un'app che accetta il comando dell'utente. Il comando utente viene utilizzato in questo formato:Come semplificare questa logica/codice?

comando -parameter

Ad esempio, l'applicazione può avere "Copia", "Incolla", "Cancella" comando Sto pensando il programma dovrebbe funziona così:

public static void main(String args[]){ 

    if(args[0].equalsIgnoreCase("COPY")){ 
    //handle the copy command 

    } else if(args[0].equalsIgnoreCase("PASTE")){ 
    //handle the copy command 


    }/** 
    code skipped 
    **/ 


} 

Così, funziona, ma penso che diventerà sempre più complessa quando ho più il comando nel mio programma, anche, è diverso da leggere. Qualche idea per la semplice logica?

+3

vedere anche http://stackoverflow.com/questions/1199646 – dfa

risposta

7

Se si è preoccupati di che gestisce i parametri della riga di comando, per questo si intende Commons CLI.
passare attraverso il CommandLineParser

e se siete preoccupati per la complessità del vostro if-else quindi è possibile utilizzare modello di comando

public interface Command { 
    void exec(); 
} 

public class Copy implements Command {  
    void exec() { 
      // your copy Code 
    } 
} 

public class Paste implements Command {  
    void exec() { 
      // your Paste Code 
    } 
} 


public class Delete implements Command {  
    void exec() { 
      // your Delete Code 
} 

- poi

public static void main(String args[]){ 
Map commandMap<String,Command> = new HashMap<String,Command>(); 
commandMap.put("Copy", new Copy()); 
commandMap.put("Paste", new Paste()); 
commandMap.put("Delete", new Delete()); 

if (commandMap.containsKey(args[0])){ 
commandMap.get(args[0]).exec(); 

} 
} 
+1

+1 questa è la risposta. Sarei anche molto tentato di usare reflection per creare la classe Command dalla String passata per eliminare il requisito di compilare commandMap che potrebbe diventare oneroso e un po 'disordinato all'aumentare del numero di comandi. – Robin

+0

+1 Sì, questo sarebbe il mio suggerimento anche se vuoi liberarti delle clausole 'if' e renderlo un po 'più flessibile. –

3

Utilizzare una libreria per mantenere il disordine dell'argomento della riga di comando analizzando il codice, ad esempio args4j.

7

A seconda di come semplice la sintassi della riga di comando è, un semplice enum può essere la vostra soluzione

public enum Command { 
    COPY { 
     @Override void execute() { 
      System.out.println("Copying..."); 
     } 
    }, 
    PASTE { 
     @Override void execute() { 
      System.out.println("Pasting..."); 
     }  
    }, 
    DELETE { 
     @Override void execute() { 
      System.out.println("Deleting...");   
     } 
    }, 
    ; 

    abstract void execute(); 

    public static void main(String args[]) { 
     Command c = Command.valueOf(args[0].toUpperCase()); 
     c.execute(); 
    } 
} 

Compilare ed eseguire questo con java Command paste, java Command bleh, ecc ti consigliamo di passare il resto della args a l'enum nel tuo codice di produzione. Inoltre, valueOf genera IllegalArgumentException se non viene trovata una costante enum con il nome specificato.


Se la sintassi cresce fino a essere più complessa, però, si consiglia di utilizzare le librerie specificamente progettati per la linea di comando l'analisi, ad esempio, Apache Commons CLI.

+2

Questo non è molto meglio di un mucchio di if/elseifs. Se stai usando le enumerazioni sarebbe molto più bello spostare la logica in un metodo dell'enumerazione, quindi puoi semplicemente usare Command.valueOf (...). Execute() invece di tutto il controllo o la commutazione disordinati. – Chris

+0

Grazie per il suggerimento! Aggiunto! – polygenelubricants

+1

Questo è abbastanza bello ora in termini di quantità di codice, anche se un po 'magico. – msandiford

0

Esistono molte librerie in grado di gestire questa situazione anziché scrivere tutto il codice.

1

Quando Vedo un sacco di codice if/then/else, penso immediatamente al polimorfismo come una possibile soluzione.

Un'interfaccia di comando e una mappa sarebbero un ottimo modo per risolvere questo problema. Se dovessi scrivere questo in Java, potrebbe assomigliare a questo:

public interface Command<T, V> 
{ 
    V execute(T parameter) throws Exception; 
} 

Se le operazioni sono multi-threaded, si può semplicemente riutilizzare l'interfaccia Runnable per i comandi che non restituiscono un valore e Callable <T> per quelli che lo fanno

In entrambi i casi, ora il tuo costrutto if/then/else è una mappa in cui la chiave è il nome e il valore è l'oggetto Command. Cerchi un comando fornendo la chiave del nome.Aggiungi un nuovo comando scrivendo una nuova implementazione dell'interfaccia di comando e aggiungendola alla mappa. L'inizializzazione della mappa è qualcosa che fai all'avvio. Puoi anche esternalizzarlo come configurazione in modo da non dover modificare il codice per aggiungerne di nuovi (Principio Aperto/Chiuso).

Problemi correlati