天天看點

指令模式(我的了解)

前言

第一章:通常的指令模式

第二章:簡化的指令模式

第三章:其他要說的内容

    以下是我對指令模式的了解。可能和很多其他文章講述的不太一樣。經過我了解加工的。供大家參考!學藝不精,并且寫的比較倉促,還請大家指教。

<b>1.1通常指令模式有一下幾個角色</b>

調用者:(指令的執行者)

生成有序的指令隊列

按順序執行指令操作

提供撤銷指令操作

記錄已經操作的指令

抽象指令:

抽象的指令接口

具體指令:

具體的指令。

由三個要素組成:執行者,執行者要作的操作和被執行的對象組成。當然還可以有其他,比如将對象執行成什麼結果。例如:調用Mypait類(執行者)将My rectangle(對象)填充(操作)為紅色(結果)。這樣就可以完全描述一個指令了。

執行者:

真正執行邏輯操作的對象

<b>1.2原型:</b>

<b></b> 

//調用者

public class Invoker{

List commands;  //指令集合

public void setCommands(List commands){

  this.commands = commands;

}

public void addCommand (Command command,int i){

commands.add(i,command);

public void removeCommand (int i){

//得代執行指令

public void action(){

       <b>for</b>(Iterator it = list.iterator();it.hasNext();){

          Command  command = Command) it.next();

          Command. execute();

     }

……………

//還可以有豐富的redo和undo操作;(當然一些都給基于指令類提供的相應方法)

//抽象指令

abstract class Command

  abstract public void execute();

abstract public void unexecute();

abstract public void reexecute();

//一般有這樣這個方法,根據需要可以增删

// 具體的指令類1:寫作指令,選擇一個作者(Author類執行個體對象),讓他寫作(調用它的write方法)寫作的對象是書(Book的執行個體對象)形成了一個寫作的指令,寫作的對象是Book的執行個體

public class WriteCommand implement Command

{

  Author author;      //執行者

  Book book;          //要執行的對象

  public WriteCommand (Author author,Book book) {

   this. author = author;

   this. book = book;

 }

  // 在這裡執行要執行的操作

  public override void Execute()

  {

    author.write (book);

  }

// 具體的指令類2: 出版指令,選擇一個出版社(publisher類執行個體對象),讓他出版書(調用它的publisherBook方法)出版的對象是書(Book的執行個體對象)形成了一個出版的指令

public class PublishCommand implement Command

  Publisher publisher;

Book book;

  public PublishCommand (Publisher publisher) {

   this. publisher = publisher;

  // Methods

    publisher. publisherBook(book);

// Publisher和Author類為執行者

這樣我們的用戶端代碼就可以這樣寫:

//如果我要出一本書

//一本空白的書

Book book = new Book();

//先找一個作者和出版社

Author author = new Author();

Publisher publisher = new Publisher ();

//産生指令集合

Command writeCommand = new WriteCommand (author,book);

Command publishCommand = new PublishCommand(publisher,book);

List commands = new List ();

Commands.add(writeCommand);

//找個調用者,把指令給它,讓他來根據指令協調工作

Invoker invoker = new invoker();

Invoker.setCommands(commands);

invoker.action();

特點:

1》分布登記統一執行:

在作程式時,經常碰到一些需求,先注冊一些操作,并不馬上執行,等最終确定後統一執行。如一個具體的例子:使用者定制自己的報表,可以訂閱餅,柱,折線,曲線圖,客戶選擇相應的報表組合,這樣對應一個指令集合,在沒确定之前使用者可以增删這些報表(指令),等最終确定統一交給調用者根據指令執行,生成組合報表。實作了指令分布提出,确定後統一執行的功能。

2》形如流水線操作:還是出書的例子

//先是一本空白的書:

//找幾個作者

Author author1 = new Author();

Author author2 = new Author();

//把寫1,2章的名類分别給這兩個作者

Command writeCommand = new Write1Command (author1,book);

Command writeCommand = new Write2Command (author2,book);

//流水寫書

invoker.action()

實際上在aciton這一方法中,invoker按照指令,讓兩個作者流水寫作這本書。(類似一個書的流水線加工工廠)

這樣我們的書就被流水加工成功(當然這本書隻有兩章)

這樣就給了我們一種系統設計的架構,

模型+工具+指令

用戶端産生指令,指令調用工具操作模型。

Book 相當于模型

Author 相當于和多工具類中的一個

Command 指令

3》系統需要支援指令的撤消(undo)。提供redo()方法

我們可以和容易的加入undo和redo,這個不難了解

4》在Invoker中我們可以實作跟蹤,和日志。

5》當系統需要為某項複制增加形的功能的時候,指令模式使新的功能(表現為一種指令)很容易地被加入到服務種裡。

指令聯系了工具類即執行類和系統邏輯,

指令模式的角色比較多,在實際應用種我們可以根據所需要的功能和不需要的功能加以簡化。

1》去掉調用者

産生指令集合後,我們可以直接在client中疊代執行執行操作

2》變化 調用者 成為 跟蹤者

List commands;  //已經執行完畢的指令集合

public void action(Command  command){

         //執行操作

          command. execute();

           //

          commands.add(command);

這樣這個類就記錄了所有執行過的操作。

3》去掉 指令 用map替代

我們完全可以用map代替指令,這樣無需定義各種指令類

我們改進例子

Map m = <b>new</b> HashMap;

m.put(author, write);

m.put(author, publisherBook);

在Invoker的action方法:

得代map

運用java反射來調用方法;

4》去掉執行者:

直接在指令中(execute方法種)加業務邏輯。這樣隻适合于簡單的小的系統.

1》  将某些參數傳給某個方發的方式很多,除了當作方法的參數外還可以當作類的成員便倆變量傳入:

這就為指令的抽象帶來了極大的友善

當我們已經有了執行者(類Test)方法execute(args1,args2 ….argsn)

我們不必向Command加入execute(args1,args2 ….argsn)抽象方法,在說即使加了,在我們疊代的時候也無法判斷或十分不容易判斷哪個指令調用哪個execute方法。

那麼我們可以這樣

class ConcreteCommand : Command

  Test test;

   args1

args2

…..

argsn

    test. execute (args1,args2 ….argsn);

2》在想跟蹤操作的時候,一般為每一個操作對象配置設定一個調用者,操作對象在調用者中設定。(可以抽象出一個總的調用者,來協調調用每一個具體的調用者)

3》指令的抽象粒度我覺得是要注意的。

4》了解思想,不要機械的照搬。消化成自己的,加以靈活的運用和創造在是根本出路。

所謂指令模式的根本思想就是在 先形成指令,在根據指令執行。