2010-03-20 396 views
5

我想寫一個接受用戶命令的應用程序。用戶命令此格式中使用:如何簡化這個邏輯/代碼?

命令-parameter

例如,應用程序可以有「複製」,「粘貼」,「刪除」命令 我想程序應該這樣的工作:

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


} 

所以,它的工作原理,但我認爲它會變得越來越複雜,當我在我的程序有更多的命令,而且,不同的閱讀。任何想法只是邏輯?

+3

另請參閱http://stackoverflow.com/questions/1199646 – dfa 2010-03-20 10:31:35

回答

7

如果您擔心處理命令行參數那麼Commons CLI就是這個意思。
經過CommandLineParser

,如果你關心你的的if-else那麼你可以使用命令模式的複雜性

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 
} 

- 然後

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這是答案。我也非常想用反射來創建從傳入的字符串中的Command類,以擺脫構建命令映射的需求,隨着命令數量的增加,這個命令可能變得繁重並且有些雜亂。 – Robin 2010-03-20 11:12:50

+0

+1是的,這也是我的建議,如果你想擺脫你的'if'子句並使其更靈活一點。 – 2010-03-20 11:39:28

3

使用一個庫來保持命令行參數解析出您的代碼的混亂,例如args4j

7

根據您的命令行語法是多麼簡單,簡單的enum可能是您的解決方案

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

編譯和運行java Command paste此,java Command bleh,等你要的args其餘傳遞給生產代碼中的枚舉。另外,如果未找到具有指定名稱的枚舉常量,則valueOf將引發IllegalArgumentException


如果你的語法變得更復雜了,但是你可能想要使用專門爲命令行解析而設計的庫, Apache Commons CLI

+2

這並不比一堆if/elseifs好得多。如果使用枚舉將邏輯移入枚舉的方法會更好,那麼可以簡單地使用Command.valueOf(...)。execute()而不是所有混亂的檢查或切換。 – Chris 2010-03-20 10:45:07

+0

感謝您的建議!添加! – polygenelubricants 2010-03-20 10:54:10

+1

現在就代碼數量而言,這相當不錯,即使有點不可思議。 – msandiford 2010-03-20 12:16:03

0

有很多庫可以處理這種情況,而不是寫下所有的代碼。

1

當我看到很多if/then/else代碼,我立即想到多態作爲一種可能的解決方案。

命令接口和地圖將是解決此問題的好方法。如果我是用Java編寫這一點,它可能是這樣的:

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

如果你的操作是多線程的,你可以簡單地重複使用命令Runnable接口不返回值,可贖回<牛逼>爲那些做。

無論哪種情況,現在您的if/then/else結構都是一個Map,其中鍵是名稱,值是Command對象。您通過提供名稱鍵來查找命令。通過編寫一個Command接口的新實現並將其添加到Map中來添加一個新命令。初始化映射是您在啓動時執行的操作。你甚至可以將它作爲配置外化,所以你不必修改代碼來添加新的代碼(Open/Closed Principle)。