此次要介紹的是命令模式,這也是一種行爲型模式。最近反正沒有面試機會我就寫博客唄,該投的簡歷都投了。而後就繼續看書,其實看書也會給本身帶來成就感,原來之前不明白的東西,書上已經給完全的介紹清楚了,而後讀到完了就有一種恍然大悟的感受,怕本身理解的有問題,還要去網上搜各類答案來確保本身的理解確實沒問題。最近看到一句話感受頗有道理:讀書最好的目的在於,你會發現憑藉自身閱讀構建起來的小世界,能以體恤式的溫柔,消除自身的苦難。html
命令模式:將一個請求封裝爲一個對象,從而使咱們可用不一樣的請求對用戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操做。也有稱其爲動做模式的,由於經過命令是要執行一系列動做的,其實主要仍是在你的請求和處理之間加上了一箇中間人的角色,來達到分離耦合的目的。經過對中間人角色的特殊設計來造成不一樣的模式。面試
仍是舉例子吧,如今智能手機上大部分是有語音助手的,例如蘋果手機的siri,百度地圖上的小度。咱們以siri爲例子,當咱們喚起siri後想讓它給我打開微信時,siri就會把微信給打開了。這個過程就是一個體現命令模式的過程,下面用代碼來實現一下。設計模式
定義命令接口微信
public interface Command { /** * 執行命令 */ void execute(); }
打開應用命令app
public class OpenCommand implements Command { private Application app; public OpenCommand(Application app){ this.app = app; } /** * 執行命令 */ @Override public void execute() { app.on(); } }
應用抽象類ide
/** * 應用 */ public abstract class Application { /** * 打開應用 */ public abstract void on(); }
微信post
/** * 微信 */ public class WeChat extends Application{ /** * 打開應用 */ @Override public void on() { System.out.println("微信打開了!"); } }
高德地圖學習
/** * 高德地圖 */ public class AMap extends Application{ /** * 打開應用 */ @Override public void on() { System.out.println("高德地圖打開了!"); } }
語音助手Siri測試
/** * 語音助手 */ public class Siri { private Command command; /** * 設置要執行的命令 * @param command 命令 */ public void setCommand(Command command){ this.command = command; } /** * 執行命令 */ public void doCommand(){ command.execute(); } }
測試,使用this
public class Client { public static void main(String[] args) { Siri siri = new Siri(); System.out.println("嘿 siri, 打開微信。"); Application weChat = new WeChat(); Command command = new OpenCommand(weChat); //siri傳遞命令 siri.setCommand(command); siri.doCommand(); System.out.println("嘿 siri,打開高德地圖"); Application amap = new AMap(); command = new OpenCommand(amap); //siri傳遞命令 siri.setCommand(command); siri.doCommand(); } }
運行結果
嘿 siri, 打開微信。
微信打開了!
嘿 siri,打開高德地圖
高德地圖打開了!
這個例子是命令模式的最簡單實現,其實命令模式仍是有點複雜的,可是咱們仍是先從簡單的來講而後才能慢慢到複雜。
下面分析一下命令模式的結構組成,結構圖以下。
組成命令模式的角色以下所示:
Command(抽象命令者):定義命令的接口,聲明執行的方法。
ConcreteCommand(具體命令類):命令接口實現對象,是「虛」的實現;一般會持有接收者,並調用接收者的功能來完成命令要執行的操做。
Receiver(接收者):真正執行命令的對象。任何類均可能成爲一個接收者,只要它可以根據命令要求實現的相應功能。
Invoker(調用者):要求命令要求命令對象執行請求,一般會持有命令對象,能夠持有不少的命令對象。這是用戶端真正出發命令並要求命令執行相應操做的地方,也就是說,至關於使用命令對象的入口。
Client:建立具體的命令對象,而且設置命令對象的接收者。也能夠理解爲裝配者。
一、下降系統的耦合度。因爲請求者與接收者之間不存在直接引用,所以請求者與接收者之間實現徹底解耦,相同的請求者能夠對應不一樣的接收者,一樣,相同的接收者也能夠供不一樣的請求者使用,二者之間具備良好的獨立性。
二、新的命令能夠很容易地加入到系統中。因爲增長新的具體命令類不會影響到其餘類,所以增長新的具體命令類很容易,無須修改原有系統源代碼,甚至客戶類代碼,知足「開閉原則」的要求。
使用命令模式可能會致使某些系統有過多的具體命令類。由於針對每個對請求接收者的調用操做都須要設計一個具體命令類,所以在某些系統中可能須要提供大量的具體命令類,這將影響命令模式的使用。
系統須要將請求調用者和請求接收者解耦,使得調用者和接收者不直接交互。
系統須要在不一樣的時間指定請求、將請求排隊和執行請求。
其實命令模式後面還有一些是須要介紹的,例如宏命令,撤銷操做等等,可是由於今天的計劃要留出一部分時間去看其餘的知識,就下次有時間了再補充上去。
想了解更多的設計模式請查看Java設計模式學習記錄-GoF設計模式概述。