1. 程式人生 > >Command設計模式和java回撥機制的異同

Command設計模式和java回撥機制的異同

最大的區別在於命令模式的具體命令中組合了一個接收者物件,而java回撥機制中的介面的實現類中(即匿名內部類)中並沒有組合一個接收者,從而回調方法沒有繼續呼叫接收者的方法。簡而言之,java回撥機制相較command模式少了一層接收者環節。命令模式正是回撥機制的一個面向物件的替代品。

一、首先介紹回撥機制

回撥機制:一開始,一個類定義了一些個未實現的方法,並且該類並不知道這些方法具體的實現是怎麼樣的,因為只有等到執行時候才能夠知道這些方法的具體實現。等到具體要用到該類物件的時候,才對該類中的抽象方法定義實現。該實現的過程由client來實現。具體的程式碼如下所示:

回撥類

package
callback; /** * 回撥介面 * * @author typ * */ public abstract class ICallBack { /** * 需要回調的方法。即在回撥時候需要實現的方法 */ public abstract void callback(); }
需要呼叫callback的類
package callback;

/**
 * 某個類需要呼叫回撥介面中的方法
 * 
 * @author typ
 * 
 */
public class A {
	ICallBack iCallBack;

	/**
	 * 在此處呼叫回撥介面時候,要先實現該介面
	 * 
	 * @param iCallBack
	 */
	public void setICallBack(ICallBack iCallBack) {
		this.iCallBack = iCallBack;
	}

	/**
	 * 呼叫回撥介面中的方法,當然呼叫之前要先實現callback方法
	 */
	public void doSomeThing() {
		iCallBack.callback();
	}
}
測試類client
package callback;

/**
 * 在執行的時候才能確定回撥方法的具體實現
 * 
 * @author typ
 * 
 */
public class Client {
	public static void main(String[] args) {
		A a = new A();

		a.setICallBack(new ICallBack() {

			/* 此處在建立ICallBack物件時候,定義callback函式的方法體
			 * (non-Javadoc)
			 * @see callback.ICallBack#callback()
			 */
			public void callback() {
				
system
.out.println("A is running, and call back is running!"); } }); a.doSomeThing(); } }

二、command設計模式

命令模式是對命令的封裝。命令模式把發出命令的呼叫方和執行命令的接收方分割開,對兩者之間解耦。

每一個命令都是一個操作:呼叫方發出請求要求執行一個操作;接收方收到請求,並執行操作。如果沒有命令模式,那麼,呼叫方要存放一個接收方的引用,這樣增加了他們之間的耦合性。命令模式允許呼叫方和接收方獨立開來,使得呼叫方不必知道接收方的介面,更不必知道請求是怎麼被接收,以及操作是否被執行、何時被執行,以及是怎麼被執行的。並且利用command模式還可以執行redo和undo操作。程式碼走起:

命令接收方,其實最終還是接收方來執行命令

package command;

/**
 * 命令的接收者
 * 
 * @author typ
 * 
 */
public class Receiver {
	public void execute() {
		System.out.println("receiver is executing!");
	}
}

command抽象類,儲存一個指向接收方的引用,定義了一個execute方法,在子類中是想

package command;

/**
 * 命令的抽象類,用於封裝不同型別的命令和接收者
 * 
 * @author typ
 * 
 */
public abstract class Command {
	Receiver receiver;

	Command(Receiver receiver) {
		this.receiver = receiver;
	}

	public abstract void execute();

}

command的具體子類

package command;

public class ConcreteCommand extends Command {
	ConcreteCommand(Receiver receiver) {
		super(receiver);
	}

	public void execute() {
		receiver.execute();
	}
}

呼叫方,儲存一個指向命令command的引用,可以傳入任何具體的command

package command;

/**
 * 呼叫者
 * 
 * @author typ
 * 
 */
public class Invoker {
	Command command;

	public Invoker() {
	}

	/**
	 * 執行command
	 */
	public void invoke() {
		command.execute();
	}

	public void setCommand(Command command) {
		this.command = command;
	}
}

client測試類

package command;

/**
 * 測試類
 * 
 * @author typ
 * 
 */
public class Client {
	public static void main(String[] args) {
		Receiver receiver = new Receiver();
		Command command = new ConcreteCommand(receiver);
		Invoker invoker = new Invoker();
		invoker.setCommand(command);
		invoker.invoke();
	}
}

三、command模式如何替代回撥機制

"CallBack"講的便是先將一個函式登記上,然後在以後呼叫此函式。使用命令模式作為"CallBack"在面向物件系統中的替代。

下面我們就在回撥機制上面改,如下:

回撥類改為command類

package comm_call;

/**
 * 回撥介面--相當於Command類
 * 
 * @author typ
 * 
 */
public abstract class ICallBack {
	/**
	 * 需要回調的方法。即在回撥時候需要實現的方法
	 */
	public abstract void callback();
}

ICallBackImpl相當於ConcreteCommand

package comm_call;

/**
 * ICallBack的實現類,這個類相當於Command的具體實現類ConcreteCommand
 * @author typ
 *
 */
public class ICallBackImpl extends ICallBack {

	public void callback() {
		System.out.println("A is running, and call back is running!");
	}

}

呼叫方類

package comm_call;

/**
 * 該類作為呼叫方類
 * 
 * @author typ
 * 
 */
public class A {
	ICallBack iCallBack;

	/**
	 * 在此處呼叫回撥介面時候,要先實現該介面
	 * 
	 * @param iCallBack
	 */
	public void setICallBack(ICallBack iCallBack) {
		this.iCallBack = iCallBack;
	}

	/**
	 * 呼叫回撥介面中的方法,當然呼叫之前要先實現callback方法
	 */
	public void doSomeThing() {
		iCallBack.callback();
	}
}

測試類Client

package comm_call;

/**
 * 在執行的時候傳入command物件,而不是實現回撥方法
 * 
 * @author typ
 * 
 */
public class Client {
	public static void main(String[] args) {
		A a = new A();
		ICallBackImpl iCallBackImpl = new ICallBackImpl();
		// 此處傳入iCallBackImpl是一個命令的物件,回撥機制中此處傳入的是一個回撥類
		a.setICallBack(iCallBackImpl);
		a.doSomeThing();
	}
}