2010-03-20 70 views
5

Tôi muốn viết một ứng dụng chấp nhận lệnh của người dùng. Lệnh dùng sẽ được sử dụng trong định dạng này:Làm thế nào để đơn giản hóa logic/mã này?

lệnh -parameter

Ví dụ, ứng dụng có thể có "Copy", "Dán", "Xóa" lệnh Tôi nghĩ chương trình nên làm việc như thế này:

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


} 

Vì vậy, nó hoạt động, nhưng tôi nghĩ nó sẽ trở nên ngày càng phức tạp khi tôi có thêm lệnh trong chương trình của mình, cũng khác. Bất kỳ ý tưởng chỉ đơn giản là logic?

+3

xem thêm http://stackoverflow.com/questions/1199646 – dfa

Trả lời

7

Nếu bạn lo ngại về việc xử lý các tham số dòng lệnh thì có nghĩa là Commons CLI là dành cho việc này.
Đi qua các CommandLineParser

và nếu bạn lo lắng về sự phức tạp của if-else sau đó bạn có thể sử dụng Pattern Command

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 
} 

- sau đó

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 đây là câu trả lời. Tôi cũng rất cám dỗ khi sử dụng sự phản chiếu để tạo ra lớp Command từ String được truyền vào để loại bỏ yêu cầu để xây dựng commandMap có thể trở nên nặng nề và hơi lộn xộn khi số lượng lệnh tăng lên. – Robin

+0

+1 Vâng, đây cũng là gợi ý của tôi nếu bạn muốn loại bỏ các mệnh đề 'if' của bạn và làm cho nó linh hoạt hơn một chút. –

3

Sử dụng thư viện để giữ cho sự lộn xộn của đối số dòng lệnh phân tích cú pháp khỏi mã của bạn, ví dụ: args4j.

7

Tùy thuộc vào cách đơn giản cú pháp dòng lệnh của bạn là một đơn giản enum có thể giải pháp của bạ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(); 
    } 
} 

Biên dịch và chạy này với java Command paste, java Command bleh, vv Bạn sẽ muốn vượt qua phần còn lại của args để enum trong mã sản xuất của bạn. Ngoài ra, valueOf ném IllegalArgumentException nếu không tìm thấy hằng số enum nào với tên được chỉ định.


Nếu cú ​​pháp của bạn phát triển phức tạp hơn, bạn có thể muốn sử dụng thư viện được thiết kế riêng cho phân tích cú pháp dòng lệnh, ví dụ: Apache Commons CLI.

+2

Điều này không thực sự tốt hơn nhiều so với một đống if/elseifs. Nếu bạn đang sử dụng enums nó muốn được nhiều đẹp hơn để di chuyển logic vào một phương pháp của enum, sau đó bạn chỉ có thể sử dụng Command.valueOf (...). Execute() thay vì tất cả các kiểm tra lộn xộn hoặc chuyển đổi. – Chris

+0

Cảm ơn bạn đã đề xuất! Thêm! – polygenelubricants

+1

Điều này là khá tốt đẹp bây giờ về số lượng mã, ngay cả khi một chút ma thuật. – msandiford

0

Có nhiều thư viện có thể xử lý tình huống này thay vì viết tất cả mã xuống.

1

Khi Tôi thấy rất nhiều nếu/sau đó/mã khác, tôi ngay lập tức nghĩ về đa hình như một giải pháp có thể.

Giao diện lệnh và Bản đồ sẽ là cách tốt để giải quyết vấn đề này. Nếu tôi được viết những dòng này trong Java, nó có thể trông như thế này:

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

Nếu hoạt động của bạn là đa luồng, bạn chỉ có thể tái sử dụng các giao diện Runnable cho lệnh mà không trả về giá trị và Callable <T> cho những người làm.

Trong cả hai trường hợp, giờ đây nếu cấu trúc if/then/else của bạn là Bản đồ trong đó khóa là tên và giá trị là đối tượng Command. Bạn tìm kiếm một Lệnh bằng cách cung cấp khóa tên.Bạn thêm một lệnh mới bằng cách viết một triển khai mới của giao diện Lệnh và thêm nó vào Bản đồ. Khởi tạo Bản đồ là thứ bạn làm khi khởi động. Bạn thậm chí có thể ngoài nó làm cấu hình để bạn không phải sửa đổi mã để thêm mã mới (Nguyên tắc Mở/Đóng).

Các vấn đề liên quan