JAVA設計模式之 命令模式【Command Pattern】

小呂-ICE發表於2014-11-19

一、概述

    命令模式可以將請求傳送者和接收者完全解耦,傳送者與接收者之間沒有直接引用關係,傳送請求的物件只需要知道如何傳送請求,而不必知道如何完成請求。核心在於引入了命令類,通過命令類來降低傳送者和接收者的耦合度,請求傳送者只需指定一個命令物件,再通過命令物件來呼叫請求接收者的處理方法,命令模式是一種物件行為型模式。


二、使用場景

1>、系統要求請求傳送者和接收者的解耦,使得呼叫者和接收者不直接互動;

2>、類似訊息 請求/命令 佇列處理;[命令裝載在集合或佇列中,通過遍歷集合,達到命令的批量處理]

3>、當執行一個命令而觸發多個具體命令的執行,從而實行對命令的批量處理,這種命令被稱為組合命令或巨集命令;


三、UML類圖


四、參與者

1>、Command(抽象命令類):抽象命令類一般是一個抽象類或介面,在其中宣告瞭用於執行請求的execute()等方法,通過這些方法可以呼叫請求接收者的相關操作。

2>、ConcreteCommand(具體命令類):具體命令類是抽象命令類的子類,實現了在抽象命令類中宣告的方法,它對應具體的命令接收者物件,將接收者物件的動作繫結其中。在實現execute()方法時,將呼叫接收者物件的相關操作(operation)。

3>、Invoker(命令發起者/訊息請求者):與抽象命令類存在關聯關係,在命令發起時 將一個具體命令物件注入其中 再呼叫具體命令物件的執行方法(execute) 從而間接實現呼叫請求接收者的相關操作。

4>、Receiver(命令/訊息 接收者):接收者執行與請求相關的操作,它具體實現對請求的業務處理(operation方法執行)。

 

五、用例學習

1、命令接收者A:ReceiverA.java

/**
 * 命令接收者A
 * @author  lvzb.software@qq.com
 *
 */
public class ReceiverA {

	public void operation(){
		System.out.println("我是命令接收者A,我已接收到命令,正在執行相應的業務操作方法");
	}
}
2、命令接收者B:ReceiverB.java

/**
 * 命令接收者B
 * @author  lvzb.software@qq.com
 *
 */
public class ReceiverB {

	public void operation(){
		System.out.println("我是命令接收者B,我已接收到命令,正在執行相應的業務操作方法");
	}
}
3、抽象命令類:Command.java

/**
 * 命令抽象類
 * @author  lvzb.software@qq.com
 *
 */
public abstract class Command {

	public abstract void execute();
}
4、具體命令類A:ConcreteCommandA.java

/**
 * 具體命令類A<br/>
 * 與命令接收者ReceiverA 關聯
 * @author  lvzb.software@qq.com
 *
 */
public class ConcreteCommandA extends Command {

	private ReceiverA receiver;
	
	public ConcreteCommandA(){
		receiver = new ReceiverA();
	}
	
	@Override
	public void execute() {
		// 呼叫具體命令接收者的執行方法
		receiver.operation();
	}

}
5、具體命令類B:ConcreteCommandB.java

/**
 * 具體命令類B<br/>
 * 與命令接收者ReceiverB 關聯
 * @author  lvzb.software@qq.com
 *
 */
public class ConcreteCommandB extends Command {

    private ReceiverB receiver;
	
	public ConcreteCommandB(){
		receiver = new ReceiverB();
	}
	
	@Override
	public void execute() {
		// 呼叫具體命令接收者的執行方法
		receiver.operation();
	}

}
6、命令傳送者/訊息請求者:Invoker.java

/**
 * 命令/訊息傳送者
 * @author  lvzb.software@qq.com
 *
 */
public class Invoker {
	// 維護一個抽象命令類的引用
	private Command command;
	
	/**
	 * 對具體命令物件的引用
	 * @param command
	 */
	public void setCommand(Command command){
		this.command = command;
	}
	
	/**
	 * 傳送命令<br/>
	 * 呼叫具體命令執行類,間接的將訊息/命令傳遞給了命令接收者執行
	 */
	public void runCommand(){
		command.execute();
	}

}
7、客戶端測試類:Client.java

public class Client {

	public static void main(String[] args) {
		Command command = null;
		/*
		 * 如果要使命令傳送給 命令接收者B(ReceiverB)處理
		 * 則只要例項化與ReceiverB 相關的命令類ConcreteCommandB即可
		 * 程式碼修改如下:
		 * command = new ConcreteCommandB();
		 * 
		 * 以下是例項化命令類ConcreteCommandA 及將命令訊息傳送給與之關聯的ReceiverA處理
		 */
		command = new ConcreteCommandA();
		Invoker invoker = new Invoker();
		invoker.setCommand(command);
		invoker.runCommand();
	}

}

六、其他



相關文章