設計模式_命令模式

定義
    Encapsulate a request as an object ,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數化,對請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢復功能)

不認識的單詞
Encapsulate  封裝
thereby  從而
parameterize 用參數表示,參數化
undoable   可撤銷

類圖  

接受者Recevier:定義每個接受者要完成的任務(類似於一個工具類)
Command抽象類,有一個execute方法        (類似於一個組裝機器圖)
ConcreteCommand子類,成員爲一個抽象類,execute方法時就調用接受者的方法 (類似於一個組裝機器)
Invoker 有一個Command成員,action方法就是執行execute方法(在我看來,這個有點多餘了)
總之就是這樣的,Command封裝Receiver,Invoker封裝Command


public abstract class Group {
 public abstract void find();
 public abstract void add();
 public abstract void delete();
 public abstract void change();
 public abstract void plan();
}

public abstract class Command {
 
 protected RequirementGroup rg=new RequirementGroup();
 protected PageGroup pg=new PageGroup();
 protected CodeGroup cg=new CodeGroup();
 
 public abstract void execute();
}
public class Invoker {
 private Command command;
 
 public void setCommand(Command command){
  this.command=command;
 }
 
 public void action(){
  this.command.execute();
 }
}


三個子類

public class CodeGroup extends Group {

 @Override
 public void add() {
  System.out.println("add code");
 }

 @Override
 public void change() {
  System.out.println("change code");
 }

 @Override
 public void delete() {
  System.out.println("delete code");
 }

 @Override
 public void find() {
  System.out.println("find code");
 }

 @Override
 public void plan() {
  System.out.println("plan code");
 }
}

public class PageGroup extends Group {

 @Override
 public void add() {
  System.out.println("add page");
 }

 @Override
 public void change() {
  System.out.println("change page");
 }

 @Override
 public void delete() {
  System.out.println("delete page");
 }

 @Override
 public void find() {
  System.out.println("find page");
 }

 @Override
 public void plan() {
  System.out.println("plan page");
 }
}

public class RequirementGroup extends Group {

 @Override
 public void add() {
  System.out.println("add requirement");
 }

 @Override
 public void change() {
  System.out.println("change requirement");
 }

 @Override
 public void delete() {
  System.out.println("delete requirement");
 }

 @Override
 public void find() {
  System.out.println("find requirement");
 }

 @Override
 public void plan() {
  System.out.println("plan requirement");
 }
}

現在根據需要來一個一個的寫命令,非常好擴展

public class AddRequirementCommand extends Command {

 /**
  * 執行增加一項需求的命令
  */
 @Override
 public void execute() {
  super.rg.find();
  super.rg.add();
  super.rg.plan();
 }
}

public class DeletePageCommand extends Command {
 
 /**
  * 刪除頁面的命令
  */
 @Override
 public void execute() {
  super.pg.find();
  super.rg.delete();
  super.rg.plan();
 }
}

好了,命令已經寫好了。

如何調用呢?  直接調用這個類的execute方法不就行了嗎? 爲了更加體現依賴關係和系統設計特點(無論接受了什麼命令,都要接受和執行),調用者和接受者沒有任何依賴關係。調用者只需要調用Command抽象類的execute方法即可,不需要了解誰執行了。

public class Client {

  
 public static void main(String[] args) {
  Invoker invoker=new Invoker();
  System.out.println("--------客戶要求增加一項需求-------------");
  Command command = new AddRequirementCommand();  //使用早就寫好的東西 
  command.execute();
  invoker.setCommand(command);
  invoker.action();
 }
}
/*高內聚
 *調用者Invoker和接受者Group沒有依賴,Command容易擴展
 *缺點就是如果Command子類多的話,需要N多個的子類去一個一個實現 
 */

悟: 在我看來,這個擴展性是好的,但是寫的沒有技術含量,因爲每多一項,就需要寫一個組合命令來供客戶調用,同樣Invoker的存在也是爲了好看而已,本質是組裝,加工。
     和中介者不同的是這裏的業務各個子類是相同的,而中介者是不同的。


優點 
    類間解耦
    可擴展性好
  
缺點
    類容易膨脹


我是菜鳥,我在路上。

發佈了78 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章