命令模式提供一個處理使用者請求的標準介面。每個請求被封裝名為Command的對象中。命令模式中的三個類分別是:Command、CommandManager和Invoker。
Command
Command類表示單個行為的封裝。應用程式中的每個行為,例如儲存或者刪除,都會被建模為命令。這樣,應用程式的行為就是命令對象的集合。要嚮應用程式添加行為,開發人員要做的就只是實現附加的命令對象。
如下:
package command;public interface Command {public void execute();}
Command介面,只是含有一個execute方法,其它的實現Command介面的類(DefaultCommand )就是一個命令,如下:
package command;public class DefaultCommand implements Command{public void execute(){System.out.println("DefaultCommand命令執行中...");}}
當然,也可以擴充Command介面,實現更多的功能:
package command;import java.util.Collection;import java.util.Map;/** * 擴充自Command介面,ManagedCommand實現了該介面 * */public interface ManagedLifecycle extends Command{public void setApplicationContext(Map context);//用於傳輸需要的應用程式資料public void initialize();//初始化方法public boolean isValidated();//執行驗證public Collection<?> getErrors();//擷取錯誤資訊public void destory();//銷毀}
下面是實現ManagedCommand類,實現了ManagedLifecycle,也是一個命令:
package command;import java.util.Collection;import java.util.HashMap;import java.util.Map;/** * 比DefaultCommand功能豐富很多,首先傳遞需要的應用程式資料,調用初始化方法,執行驗證,最後執行命令 * * */public class ManagedCommand implements ManagedLifecycle{private Map<?,?> context;private Map<?,?> errors = new HashMap();//初始化public void initialize() {System.out.println("初始化...");}//執行public void execute() {System.out.println("ManagedCommand命令執行中...");}//銷毀public void destory() {System.out.println("銷毀中...");}//是否驗證成功public boolean isValidated() {System.out.println("驗證成功...");return true;}public void setApplicationContext(Map context) {System.out.println("傳輸應用程式資料...");this.context = context;}//擷取錯誤資訊public Collection<?> getErrors() {return errors.values();}}CommandManager
命令模式的下一個組件CommandManager,該類負責管理對應用程式可用的命令。下面的CommandManager,處理所有的請求,使用一個HashMap,所有的命令將在請求處理之前被初始化,然後通過名稱被擷取
package command;import java.util.Collection;import java.util.HashMap;import java.util.Map;/** * 處理所有的請求,使用一個HashMap,所有的命令將在請求處理之前被初始化,然後通過名稱被擷取 * */public class CommandManager {private Map<String, Command> commands = new HashMap<String, Command>();public void add(String name, Command command){commands.put(name,command);}public Command getCommand(String name){return commands.get(name);}}Invoker
負責按照一定方式執行命令類。看下面的Client類:
package command;import java.util.Collection;import java.util.HashMap;import java.util.Map;/** *一個單獨的用戶端可以掩飾命令模式的執行。單調用Client構造憾事是,它想管理器添加 */public class Client {private Map context = new HashMap();private CommandManager manager = new CommandManager();public Client(){manager.add("default", new DefaultCommand());//一個新的命令添加到CommandManager中去manager.add("Managed", new ManagedCommand());}public void invoke(String name){Command command = manager.getCommand(name);//確定被執行的命令是否實現了ManagedLifecycle介面if(command instanceof ManagedLifecycle){ManagedLifecycle managed =(ManagedLifecycle) command;managed.setApplicationContext(context);managed.initialize();if(managed.isValidated()){managed.execute();}else{Collection<?> error = managed.getErrors();}managed.destory();}else{command.execute();}}public static void main(String[] args){Client client = new Client();System.out.println("1、執行DefaultCommand命令:");client.invoke("default");System.out.println("2、執行ManagedCommand命令:");client.invoke("Managed");}}
運行結果:
允許用戶端Invoker將資源傳遞到命令中是一個非常強大的概念,被稱為反向控制(inversion of control,IOC)或依賴關係注入。它無需Command類去尋找可用於invoker的服務和資源。
命令模式例子:使用命令模式,告別if-else