命令模式

为什么引用命令模式

当需求变动比较频繁,如果没有一个具体的负责人的话,那我们每次都必须将项目相关人员带上,去和客户讨论需求,这样做的结果是人力成本过高,而且过去麻烦,如果可以有个负责人,负责只需接受客户的命令需求,就立刻通知相关负责部门进行执行就可以方便很多了,这就是为什么引入命令模式。

命令模式是什么

将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。

核心思想

Command:命令接口,提供所有命令实现类必须实现的方法。

ConcreteCommand:具体命令,包含Receiver对象,通过Execution方法,调用Receiver的Action方法。

Invoker:调用者,包含一个command对象,可以执行command的execute()方法

Receiver:接受者,定义了接受者该做的操作,不同的具体接受者可以实现不同的操作。

具体案例

按钮点击,接受到点击不同的按钮,实现不同的功能,使用命令模式实现。

UML:

代码

package com.dong.Command;

public interface Button {
	public void Execute();
}

package com.dong.Command;

public class CloseButtonReceiver {
	public void Do() {
		System.out.println("Close the machine");
	}
}

package com.dong.Command;

public class OpenButtonReceiver {
	public void Do() {
		System.out.println("Start the machine ");
	}
}

package com.dong.Command;

public class BlueButton implements Button {
	private CloseButtonReceiver receiver;

	public BlueButton(CloseButtonReceiver receiver) {
		this.receiver = receiver;
	}
	
	@Override
	public void Execute() {
		// TODO Auto-generated method stub
		receiver.Do();
	}

}

package com.dong.Command;

public class RedButton implements Button {
	
	public OpenButtonReceiver receiver ;
	
	public RedButton(OpenButtonReceiver receiver) {
		this.receiver = receiver;
	}
	@Override
	public void Execute() {
		receiver.Do();
	}

}

package com.dong.Command;

public class Invoker {
	
	private Button button;
	
	public void setButton(Button button) {
		this.button = button;
	}
	public void action() {
		this.button.Execute();
	}
}

package com.dong.Command;
/**
 * 执行结果:
 *  Start the machine 
 *  Close the machine
 * @author liuD
 *
 */
public class client {
	public static void main(String[] args) {
		//负责人,负责接收命令,分配任务,让具体的执行者执行
		Invoker invoker  = new Invoker(); 
		//不同的接受者,即执行命令的主体,可以由多个接受者,每个接受的执行方式不同
		OpenButtonReceiver receiver =new OpenButtonReceiver();
		//将命令传递给特定的接受者
		Button redbutton = new RedButton(receiver);
		//负责人将命名分配给特定的负责人
		invoker.setButton(redbutton);
		//负责人让具体接受人开始干活,具体的接受者开始执行相应的操作。
		invoker.action();
		
		CloseButtonReceiver creceiver = new CloseButtonReceiver();
		Button bluebutton = new BlueButton(creceiver);
		invoker.setButton(bluebutton);
		invoker.action();
	}
}

优点

命令的接受者和执行者实现分离,解耦,

一个命令可以对应多个接受者,每个接受者可以执行不同的操作,扩展容易。

缺点

如果命令过多,则子类就需要更多。