天天看點

【設計模式十五之指令模式】指令模式細說指令模式

Command Pattern 指令模式

  • 細說指令模式
    • 細說指令模式
      • 定義
      • UML模型
      • 場景
        • 場景一
        • 場景二
      • 代碼
        • 代碼一
        • 代碼二
        • 基于UML的代碼
      • 指令模式應用和注意事項

細說指令模式

提示:

部落客:章飛 _906285288的部落格

部落格位址:http://blog.csdn.net/qq_29924041

細說指令模式

定義

指令模式(Command Pattern)是一種資料驅動的設計模式,它屬于行為型模式。請求以指令的形式包裹在對象中,并傳給調用對象。調用對象尋找可以處理該指令的合适的對象,并把該指令傳給相應的對象,該對象執行指令。

指令模式其實是将一個請求封裝成一個對象,進而讓你使用不同的請求把用戶端參數化,對請求排隊或者記錄請求日志,可提供指令的撤銷和恢複功能。

是以其實指令模式就是将指令具體化。每個指令下,所對應的響應者根據指令類型來進行做出相應的行為。

UML模型

【設計模式十五之指令模式】指令模式細說指令模式

從UML圖中看出指令模式主要分為以下幾種角色類型:

1:Conmmand 指令接口,即所有要執行的指令都需要在這裡去聲明

2:ConcreteCommand 具體的指令類型。實作Command接口

3:Receiver 指令的接受者類型。該角色其實是幹活的,指令傳遞到這裡的時候,需要Receiver去執行指令

4:Invoker 指令的調用者類型。也就是發号指令的類,持有指令對象,要求指令對象執行請求

場景

場景一

來自設計模式之禅中的案例,現在做一個項目,項目大組内又分為三個項目小組,有需求組,有代碼組,有UI組。有個項目經理,作為外部對接以及内部項目把控,調節的對象。當外部需要做一個需求變更的時候,這個時候需要對告訴項目經理,由項目經理去發号施令,排程内部的幾個項目組同僚進行修改。在這個模型中,項目經理其實就是invoker,内部的幾個項目組是receiver,而排程的過程則為指令類型。

場景二

上過國中以上的人基本上都參加過入學軍訓吧。一個教官帶一個班級,夏天站在操場上軍訓,現在回想來,也已經好多年了啊。軍訓的時候,教官有一系列的指令,比如向右看齊 向前看 稍息 立正 稍息,向左轉,齊步走,跑步走等等。每個學員在得到相應指令的時候,都要立馬切換相應動作。做錯了要被夯的啊。這個模型中,教官其實就是invoker,學員則為receiver,一系列的指令則是一個個的Command執行個體對象。

代碼

代碼一

定義抽象的組類型,每個内部項目組都需要實作

package src.com.zzf.designpattern.commandpattern.demo1;


public abstract class Group {
	//與項目組協調
	public abstract void find();
	//增加功能
	public abstract void add();
	//删除功能
	public abstract void delete();
	//修改功能
	public abstract void change();
	//變更計劃
	public abstract void plan();
	
}


           

UI組

package src.com.zzf.designpattern.commandpattern.demo1;


public class PageGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup plan");
	}

}

           

代碼組

package src.com.zzf.designpattern.commandpattern.demo1;


public class CodeGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup plan");
	}

}

           

需求組

package src.com.zzf.designpattern.commandpattern.demo1;


public class RequirementGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup plan");
	}

}

           

抽象的指令類型

package src.com.zzf.designpattern.commandpattern.demo1;


public abstract class Command {
	CodeGroup cg = new CodeGroup();
	PageGroup pg = new PageGroup();
	RequirementGroup rGroup = new RequirementGroup();
	
	
	public abstract void excuteCommand();
}

           

删除頁面的指令類型

package src.com.zzf.designpattern.commandpattern.demo1;


public class DeletePageCommand extends Command{

	@Override
	public void excuteCommand() {
		// TODO Auto-generated method stub
		super.pg.find();
		super.pg.delete();
		super.pg.plan();
	}

}

           

增加需求的指令類型

package src.com.zzf.designpattern.commandpattern.demo1;


public class AddRequirementCommand extends Command{

	@Override
	public void excuteCommand() {
		// TODO Auto-generated method stub
		super.rGroup.find();
		super.rGroup.add();
		super.rGroup.change();
		super.rGroup.plan();
	}

}

           

測試類型

package src.com.zzf.designpattern.commandpattern.demo1;


/**
 * 指令模式是在軟體開發過程中使用相對比較頻繁的一種模式,它主要有三個要素
 * Invoker 調用者,接收到指令,并執行指令,例子中我這裡項目經理就是這個角色;
 * Command(abstract) 就是指令,需要我執行的所有指令都這裡聲明;
 * Receiver  這個就是幹活的角色,指令傳遞到這裡是應該被執行的,具體到上面我們的例子中就是Group 的三個實作類;
 * @author Administrator
 * 指令模式其實是将一個請求封裝成一個對象,進而讓你使用不同的請求把用戶端參數化,對請求排隊或者記錄請求日志,可提供指令的撤銷和恢複功能
 *
 */
public class ComandPatternTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Command mCommand = new AddRequirementCommand();
		Invoker mInvoker = new Invoker();
		mInvoker.setCommand(mCommand);
		mInvoker.excuteCommand();
	}

}

           

代碼二

定義軍訓的學生

package src.com.zzf.designpattern.commandpattern.demo3;

public class Student {
	//立正
	public void  actionStandAtAttention() {
		System.out.println("軍訓學員立正");
	}
	
	//稍息
	public void  actionStandAtEase() {
		System.out.println("軍訓學員稍息");
	}
}

           

定義抽象指令

package src.com.zzf.designpattern.commandpattern.demo3;

public abstract class Command {
	Student student = new Student();
	
	public abstract void excute();
}

           

定義一個軍訓教官

package src.com.zzf.designpattern.commandpattern.demo3;

import src.com.zzf.designpattern.commandpattern.demo3.Command;

public class ArmyInstructor {
	Command mCommand = null;
	
	public void setCommand(Command mCommand){
		this.mCommand = mCommand;
	}
	
	public void excute(){
		this.mCommand.excute();
	}
}

           

定義具體的指令類型,立正指令類型

package src.com.zzf.designpattern.commandpattern.demo3;

public class StandAtAttentionCommand extends Command{

	@Override
	public void excute() {
		// TODO Auto-generated method stub
		student.actionStandAtAttention();
	}

}

           

定義稍息指令

package src.com.zzf.designpattern.commandpattern.demo3;

public class StandAtEaseCommand extends Command{

	@Override
	public void excute() {
		// TODO Auto-generated method stub
		student.actionStandAtEase();
	}

}

           

測試代碼

package src.com.zzf.designpattern.commandpattern.demo3;

import src.com.zzf.designpattern.commandpattern.demo2.ConcreteCommand;
import src.com.zzf.designpattern.commandpattern.demo2.Invoker;

public class Test {
	public static void main(String[] args) {
		ArmyInstructor mInvoker = new ArmyInstructor();
		mInvoker.setCommand(new StandAtAttentionCommand());
		mInvoker.excute();
		mInvoker.setCommand(new StandAtEaseCommand());
		mInvoker.excute();
	}
}

           

基于UML的代碼

package src.com.zzf.designpattern.commandpattern.demo2;


public abstract class Command {
	public abstract void excute();
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class ConcreteCommand extends Command{

	Receiver mReceiver = new Receiver();
	
	@Override
	public void excute() {
		// TODO Auto-generated method stub
		mReceiver.action();
	}

}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class Invoker {
	Command mCommand = null;
	
	public void setCommand(Command mCommand){
		this.mCommand = mCommand;
	}
	
	public void excute(){
		this.mCommand.excute();
	}
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class Receiver {

	public void action() {
		System.out.println("收到指令,執行操作");
	}
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


/**
 * 指令模式三要素
 * Invoker
 * Receiver
 * Command
 * @author Administrator
 *
 */
public class InvokerTest {
	public static void main(String[] args) {
		Invoker mInvoker = new Invoker();
		mInvoker.setCommand(new ConcreteCommand());
		mInvoker.excute();
	}
}

           

指令模式應用和注意事項

指令模式中調用者角色和接收者角色之間是沒有任何依賴關系的,調用者實作功能時隻要調用Command類中的執行方法就可以,不需要了解到是哪個接受者

指令模式具有很好的擴充性,如果需要添加一個指令,可以直接繼承Command類,則可以直接可以擴充

歡迎繼續通路,我的部落格