2015-10-15 31 views
0

作爲一個項目的一部分,我必須重構一些代碼,我認爲我應該實現一個命令模式設計,但我從多個角度來看它並繼續遇到問題。到目前爲止,我只是試圖從頭開始創建一些小功能,但它具有我認爲需要的所有功能。努力瞭解如何在Java中實現命令模式設計

我需要創建一個可以運行編輯器的程序,反覆詢問用戶的命令,解析這些命令並調用相應的函數,直到調用'quit'命令並退出程序。一些需要的功能是:正在工作的'currentImage'(例如,命令可能是打開,保存,單聲道等),可以存儲圖像的「緩存」(我可以'獲取'和'放入' '圖像到),諸如「上方」之類的命令將一個圖像置於另一個之上。

如果我有一個編輯器類可能看起來像這樣的:

public class Editor { 
     private ArrayList<Image> cache; 
     private Image currentImage; 

     private Parser parser; 

     public Editor(){ 
      cache = new ArrayList<Image>(); 
      parser = new Parser(); 
     } 

     public void edit() { 
      boolean finished = false; 

      while (!finished) { 
       command = parser.getCommand(); 
       finished = command.execute(command.getArgs()) 
      } 
     } 

     public boolean aNormalCommand(SomeType args) { 
      //Do interesting things with args 
      return false; 
     } 

     public boolean quit(SomeType args) { 
      //Check that the args make sense 
      return true; 
     } 

     // 
     // more normal functions 
     // 
} 

事情我卡上:

  • 如何真正使其執行所需的命令。
  • 如何正確解析輸入,以便我可以檢查用戶傳入的有效命令。我已經看過使用枚舉和/或散列表。
  • 如何簡化實際添加新功能。

當我看到讓一個Command實現一個接口來實現execute和undo,然後爲每個接受該對象的函數創建類時,我遇到了用戶想要更改當前圖像的問題 - 這將需要額外的東西來切換圖像,然後爲正確的對象攜帶新對象。

當我想到如何實現lambda時,我不知道如何使它在正確的對象上工作。而當我看到反思時,不知何故,我的命令需要找出哪個對象應該被採取行動,我不知道解析器是如何解決這個問題的。

只要'撤銷'去,我想有一個ArrayList,包含過濾器的歷史,撤消操作只是使最後一個當前(這也解決了不可撤銷的方法的問題)

希望你會告訴我,我的編輯器類不應該看起來像這樣,一切都將落實到位。

+0

我不太明白你代表「改變當前圖像」命令一類看有什麼問題。你能詳細說明一下嗎? –

+0

因爲那個類(改變當前圖像)需要保存調用類的對象(編輯器)。那可能嗎? –

+0

爲什麼?爲什麼一種命令需要持有對其適用的編輯器的引用,如果其他種類的命令不適用?我認爲你在這裏做了一些不是強制性的實施假設。不過,是的,命令對象可能會持有對其所針對的編輯器的引用。如果它的類是'Editor'的內部類,它甚至會自動得到它。 –

回答

0

您的編輯器類必須包含執行所需命令所需的字段。

需要一些特點是:「currentImage」正在被加工(例如命令可能是,打開,保存,單等),

你在你的編輯器類有一個當前圖像。它可能需要是一個BufferedImage,所以你可以執行某些命令。

一個「緩存」如果照片的工作可以被存儲(在那裏我可以「獲得」和「放」圖像),創建一個高速緩存

一種方法是有一個列表BufferedImages。

諸如「上方」之類的命令將一個圖像置於另一個之上。

現在,一個BufferedImage必須有位置信息。您可能需要創建一個子類來保存位置信息的Point或Rectangle和BufferedImage。

一旦你有一個包含所有必要字段的類(包括任何子類),那麼你可以爲你的命令創建一個接口。這裏有一個例子。

public interface Command { 

    public boolean isCommand(String command); 
    public boolean processCommand(String command); 
    public int executeCommand(); 

} 

isCommand方法標識命令。 「撤銷」就是一個例子。 Undo類將爲「撤消」命令字符串返回true。

processCommand方法分析命令。 「將圖像3移動到位置5」是必須解析的命令示例。如果該命令解析並正確驗證,則返回true,否則返回false。

executeCommand執行該命令。返回一些指示符以指示命令正確執行。我用了一個int。您可以使用枚舉。

Editor類將通過構造函數傳遞給實現此Command接口的具體類。

在您的模型類之一中,創建一個Command實例列表。然後,將實現命令界面的具體類添加到列表中。

你處理你的命令是這樣的:

public int processCommand(String command) { 
    for (Command commandObject : listOfCommands) { 
     if (commandObject.isCommand(command)) { 
      if (commandObject.processCommand(command)) { 
       int response = commandObject.executeCommand(); 
       return response; 
      } else { 
       return -1; 
      } 
     } 
    } 

    return -2; 
}