1. 程式人生 > >命令模式(Command pattern)-- 請求與實現的解耦

命令模式(Command pattern)-- 請求與實現的解耦

[align=center][size=x-large]PART 1 請求與實現[/size][/align]
[b]什麼叫請求:[/b]使用者選中一行文字,點選複製按鈕,意圖將文字複製到剪貼簿,這個意圖就叫做請求,但具體到程式中,這個請求被具象化為一個複製按鈕被點選。
[b]什麼叫實現:[/b]複製按鈕被點選之後,引發一個操作,可能就是呼叫了一個方法,該方法主要實現將當前選中的內容複製到剪貼簿,這個具體的操作就是實現。

[b]例如:[/b]有個記事本(notepad),記事本上面有個複製按鈕(copyButton)。那麼一次複製操作,就可以被分解為兩步,首選是使用者選中一行文字並單擊複製按鈕(此時觸發使用者想進行復制操作的請求),第二是複製操作被具體執行(也就是操作被實現了)。

文字往往描述的不如具體實踐來的直白,大家想象一下選中本行文字,點選假設右邊存在的“複製”按鈕,此刻是不是能想象到該行已經被快取了,可以做後面注入貼上等等的操作了。

請求和實現,都非常直觀,很容易理解。


[align=center][size=x-large]PART 2 請求與實現的耦合[/size][/align]
我們實現一個Notepad物件,順便寫了個複製和貼上的方法。這是常見的實現方式。main函式充當一個使用者去呼叫相應的方法,即做相應的請求。此時操作的被請求和操作的實現都是在Notepad裡面耦合了。


/**
* Copyright (c) 2013 by www.futeng.org
* @{#} @Notepad.java Create on @2013-6-9 @上午11:39:18
*/
package org.futeng.pattern.command;

/**
* @author <a href="mailto:
[email protected]
">futeng</a>
*/
public class NotepadTest {

public void copy() {
System.out.println("複製當前選中文字到剪貼簿...");
}

public void paste() {
System.out.println("獲取剪貼簿資料複製到當前游標後面...");
}
}


/**
* Copyright (c) 2013 by www.futeng.org
* @{#} @UserTest.java Create on @2013-6-9 @上午11:41:11
*/
package org.futeng.pattern.command;

/**
* @author <a href="mailto:
[email protected]
">futeng</a>
*/
public class UserTest {

public static void main(String[] args) {

NotepadTest notepadTest = new NotepadTest();

System.out.println("使用者選中一行文字,點選複製按鈕...");
notepadTest.copy();
System.out.println("使用者將滑鼠點在下一行,準備貼上...");
notepadTest.paste();
}
}

[quote]使用者選中一行文字,點選複製按鈕...
複製當前選中文字到剪貼簿...
使用者將滑鼠點在下一行,準備貼上...
獲取剪貼簿資料複製到當前游標後面...[/quote]

到目前為止一切都沒有問題,我們可以把複製和貼上看成是notepad所擁有的行為。但是問題會出現在真實實現的時候,這個方法體內可就不是以行輸出了,往往是擁有大量的屬性甚至是狀態的。一個方法是這樣,一個notepad少說支援這樣的操作有十幾個,想想就要死人了。
怎麼去解決,這裡面一個關鍵性的key,價值連城的思維轉變就是,把複製或者貼上這個操作也當成是一個物件。那麼notepad接受到複製或者貼上的請求的時候,直接交給相應的物件去處理。那麼程式碼的健壯性簡潔性就提高了很多。
不要以為能把複製貼上想象出作為具體物件處理不是多麼了不起的事情,看看自己的程式碼,很肯能動輒就包含了幾十個方法,很多並不是這個類在邏輯上應該能具備的功能。能細化和抽離出也是很需要業務與技術功力的。
下面看請求與實現是怎麼分離的。


[align=center][size=x-large]PART 3 請求與實現的分離[/size][/align]
package org.futeng.pattern.command;

/**
* @author <a href="mailto:
[email protected]
">futeng</a>
*/
public interface Command {
public void execute();
}

package org.futeng.pattern.command;

/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class CopyButtonCommand implements Command{
@Override
public void execute() {
System.out.println("複製當前選中文字到剪貼簿...");
}

}

package org.futeng.pattern.command;

/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class PasteButtonCommand implements Command {

@Override
public void execute() {
System.out.println("獲取剪貼簿資料複製到當前游標後面...");
}

}


/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class Notepad {

private Command copy;
private Command paste;

public Notepad() {
this.copy = new CopyButtonCommand();
this.paste = new PasteButtonCommand();
}

public void copy() {
this.copy.execute();
}

public void paste() {
this.paste.execute();
}
}

package org.futeng.pattern.command;

/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class User {
public static void main(String[] args) {
Notepad notepad = new Notepad();

System.out.println("使用者選中一行文字,點選複製按鈕...");
notepad.copy();
System.out.println("使用者將滑鼠點在下一行,準備貼上...");
notepad.paste();
}
}

這次轉變的核心思想,就是把一個方法生生抽象成一個物件了。
後面介紹一個將方法抽象物件的幾個有趣應用。

[align=center][size=x-large]PART 4 批處理實現[/size][/align]
這裡的批處理,理解為多個命令依次執行。可以想象一下很多繪圖工具的濾鏡怎麼實現的。其實就是一層一層的命令加上去。例如先磨皮再調大眼睛再上色等等。這裡實現一個“一鍵複製貼上的功能”,其實就是將當前行復制到下一行。 :D

package org.futeng.pattern.command;

/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class Notepad {

private Command copy;
private Command paste;
private Command[] batch = new Command[2];


public Notepad() {
this.copy = new CopyButtonCommand();
this.paste = new PasteButtonCommand();
this.batch[0] = this.copy;
this.batch[1] = this.paste;
}

public void copy() {
this.copy.execute();
}

public void paste() {
this.paste.execute();
}

public void copyAndPaste() {
for (Command command : this.batch) {
command.execute();
}
}
}

package org.futeng.pattern.command;

/**
* @author <a href="mailto:[email protected]">futeng</a>
*/
public class User {
public static void main(String[] args) {
Notepad notepad = new Notepad();

System.out.println("使用者選中一行文字,直接點選一鍵複製貼上按鈕");
notepad.copyAndPaste();
}
}

[quote]使用者選中一行文字,直接點選一鍵複製貼上按鈕
複製當前選中文字到剪貼簿...
獲取剪貼簿資料複製到當前游標後面...[/quote]

相關推薦

命令模式Command pattern-- 請求實現

[align=center][size=x-large]PART 1 請求與實現[/size][/align] [b]什麼叫請求:[/b]使用者選中一行文字,點選複製按鈕,意圖將文字複製到剪貼簿,這個意圖就叫做請求,但具體到程式中,這個請求被具象化為一個複製按鈕

c#設計模式系列:命令模式Command Pattern

為我 pattern 代碼 spa pro round 產生 技術分享 image 引言 命令模式,我感覺“命令”就是任務,執行了命令就完成了一個任務。或者說,命令是任務,我們再從這個名字上並不知道命令的發出者和接受者分別是誰,為什麽呢?因為我們並不關心他們是誰,發出命令

C#設計模式(15)——命令模式Command Pattern

兩個 學院 做的 text server trac handle 接受 color 一、前言   之前一直在忙於工作上的事情,關於設計模式系列一直沒更新,最近項目中發現,對於設計模式的了解是必不可少的,當然對於設計模式的應用那更是重要,可以說是否懂得應用設計模式在項目中是衡

重走Java設計模式——命令模式Command Pattern

命令模式 定義 命令模式(Command Pattern)是一種資料驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。 命令模式設計角色

設計模式命令模式Command Pattern

摘要 命令模式(Command Pattern)是一種資料驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫 介紹 意圖:將一個請求封裝成一個物件,從而使您可以用不同的請求對客戶進行引數化。 主要解決:在軟體系統中,行為請求者與行為實現者通常是一種緊

設計模式命令模式Command Pattern

/** * 命令模式。 * @author Bright Lee */ public class CommandPattern { public static void main(String[] args) { Receiver receiver = new Receiver

深入淺出設計模式——命令模式Command Pattern

轉載自:https://www.cnblogs.com/Bobby0322/p/4195240.html 模式動機 在軟體設計中,我們經常需要向某些物件傳送請求,但是並不知道請求的接收者是誰,也不知道被請求的操作是哪個,我們只需在程式執行時指定具體的請求接收者即可,此

Unity遊戲設計模式命令模式Command Pattern

        我想大部分的新人跟我一樣剛開始學習Unity的時候,控制人物行的寫法是這樣的。 using UnityEngine; using System.Collections; public class Test : MonoBehaviour { <

設計模式 —— 命令模式Command Pattern

命令模式(Command Pattern) 概念: 概述:在軟體設計中,我們經常會遇到某些物件傳送請求,然後某些物件接受請求後執行,但傳送請求的物件可能並不知道接受請求的物件是誰,執行的是什麼動作。此時可通過 命令模式 來實現,讓傳送者和接受者完全

設計模式——命令模式Command Pattern

一、命令模式的定義 將“請求”封裝成物件,以便使用不同的請求,佇列或者日誌來引數化其他物件。命令模式也支援可撤銷。 命令介面–ICommand public interface ICommand { public void execut

9.命令模式Command Pattern

1.定義 將一個請求封裝成一個物件,從而讓你使用不同的請求把客戶端引數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能。 命令模式屬於行為模式。 2.命令模式的使用場景 只要我們認為是命令的地方就可以採用命令模式,比如在GUI開發中,一個按鈕的點選是一個命令;觸

【設計模式命令模式Command Pattern

命令模式 命令模式(Command Pattern)是一種資料驅動的設計模式,它屬於行為型模式。請求以命令的形式包裹在物件中,並傳給呼叫物件。呼叫物件尋找可以處理該命令的合適的物件,並把該命令傳給相應的物件,該物件執行命令。 介紹 意圖:將一個請求封裝成一個物件,

設計模式-命令模式Command

命令模式:將一個請求封裝為一個物件,從而可用不同的請求對客戶進行引數化;對請求排隊或記錄日誌,以及支援可撤銷的操作,將”發出請求的物件”和”接收與執行這些請求的物件”分隔開來。   角色和職責: 1.Command:    宣告執行操作的介面 2.Concrete Co

Java23種設計模式【15】----》命令模式command

專案中用到的不多 一、介紹 通過抽象一個新的類,對發的請求和命令快取處理後(記錄日誌,記錄操作前狀態),再轉發給命令的執行者; 例如:資料庫事物的底層就是命令模式 二、結構 三、開發中的場景 四、類圖   五、程式碼實現  1、真正的命令執行者(

《Java模式》學習筆記之七―――建造模式Builder Pattern

問題: 當我們要建立的物件很複雜的時候(一般是由很多其它的物件組合而成),最好將物件的建立和表示分離開來,這樣做的好處就是通過一步步地進行復雜物件的建立而且每一步構造的過程引入不同的引數,使得相同的建立步驟可以得到不同的物件。 特別是一個物件的多個構造過程的順序一定時,如構造

命令模式command

命令模式:將一個請求封裝為一個物件,從而使我們可用不同的請求對客戶進行引數化;對請求排隊或者記錄請求日誌,以及支援可撤銷的操作。也稱之為:動作Action模式,事務Transaction模式。 命令模式的結構: 1.Command 抽象命令類 2.Conc

設計模式(行為型模式) ----- 命令模式Command

命令模式很好理解,舉個例子,司令員下令讓士兵去幹件事情,從整個事情的角度來考慮,司令員的作用是,發出口令,口令經過傳遞,傳到了士兵耳朵裡,士兵去執行。這個過程好在,三者相互解耦,任何一方都不用去依賴其他人,只需要做好自己的事兒就行,司令員要的是結果,不會去關注到

設計模式之 - 模板模式Template Pattern

process egg lec pass jdbcutils ima tint new sta 引入:這幾天在看一本講spring源碼的書《SPRING技術內幕》裏面在講加載配置文件的時候,可以有不同的加載方式,如根據文件系統目錄加載配置文件(FileSystemXmlAp

【java項目實戰】代理模式Proxy Pattern,靜態代理 VS 動態代理

自己 text 好的 trace use 代理 分類 plproxy this 這篇博文,我們主要以類圖和代碼的形式來對照學習一下靜態代理和動態代理。重點解析各自的優缺點。 定義 代理模式(Proxy Pattern)是對象的結構型模式,代理模

設計模式之 - 代理模式Proxy Pattern

ride proxy idt object catch 實例化 圖片 null 人在 代理模式:代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個對象的訪問。代理類負責為委托類預處理消息,過濾消息並轉發消息,以及進行消息被委托類執行後的後續處理。很多可以