2010-03-20 14 views
5

Quiero escribir una aplicación que acepte el comando del usuario. El comando de usuario se utiliza en este formato:¿Cómo simplificar esta lógica/código?

comando -parámetro

Por ejemplo, la aplicación puede tener "copia", "Pegar", "Borrar" comando Pienso en el programa debe funciona de esta manera:

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 
    **/ 


} 

por lo tanto, funciona, pero creo que va a ser cada vez más compleja cuando tenga más comandos en mi programa, también, es diferente de leer. ¿Alguna idea para simplemente la lógica?

+3

ver también http://stackoverflow.com/questions/1199646 – dfa

Respuesta

7

Si le preocupa el que maneja los parámetros de la línea de comando, entonces Commons CLI es para esto.
pasar por el CommandLineParser

y si usted está preocupado por la complejidad de su if-else, puede utilizar patrón 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 
} 

- continuación

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 esta es la respuesta. También me sentiría muy tentado de utilizar el reflejo para crear la clase de comando de la cadena pasada para eliminar el requisito de construir el mapa de comandos que podría ser oneroso y un tanto desordenado a medida que aumenta el número de comandos. – Robin

+0

+1 Sí, esta sería mi sugerencia también si desea deshacerse de sus cláusulas 'if' y hacerlo un poco más flexible. –

3

Utilice una biblioteca para mantener el desorden del análisis de la línea de comando de su código, por ejemplo args4j.

7

Dependiendo de qué tan sencilla sintaxis de línea de comandos es, un simple enum puede ser su solución

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(); 
    } 
} 

compilar y ejecutar este con java Command paste, java Command bleh, etc Usted querrá pasar el resto de args a la enumeración en tu código de producción. Además, valueOf lanza IllegalArgumentException si no se encuentra constante enum con el nombre especificado.


Si su sintaxis crece a ser más complejo, sin embargo, es posible que desee utilizar las bibliotecas diseñadas específicamente para la línea de comandos de análisis, por ejemplo, Apache Commons CLI.

+2

Esto no es mucho mejor que un montón de if/elseifs. Si está utilizando enumeraciones, sería mucho más agradable mover la lógica a un método de la enumeración, entonces simplemente puede usar Command.valueOf (...). Execute() en lugar de todas las desordenadas comprobaciones o cambios. – Chris

+0

¡Gracias por su sugerencia! ¡Adicional! – polygenelubricants

+1

Esto es bastante bueno ahora en términos de cantidad de código, aunque sea un poco mágico. – msandiford

0

Hay muchas bibliotecas que pueden manejar esta situación en lugar de escribir todo el código.

1

Cuando Veo un montón de código if/then/else, inmediatamente pienso en el polimorfismo como una posible solución.

Una interfaz de comando y un mapa sería una buena manera de resolver este problema. Si estuviera escribiendo esto en Java, que podría tener este aspecto:

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

si sus operaciones son multi-hilo, simplemente puede volver a utilizar la interfaz Ejecutable para los comandos que no devuelven un valor rescatable y <T> para los que sí lo hacen

En cualquier caso, ahora su construcción if/then/else es un Mapa donde la clave es el nombre y el valor es el objeto Command. Busca un Comando al proporcionar la clave del nombre.Agregue un nuevo comando escribiendo una nueva implementación de la interfaz de comando y agregándola al mapa. Inicializar el mapa es algo que haces al inicio. Incluso puede externalizarlo como configuración para que no tenga que modificar el código para agregar nuevos (principio abierto/cerrado).

Cuestiones relacionadas