命令模式

      原帖详见:http://javapapers.com/design-patterns/command-design-pattern/

 

    

命令设计模式是用于将请求封装成一个对象,并将其传递给一个调用者,在这里调用者并不知道怎样服务于这个请求,但是使用相应的命令可以执行响应的动作。

为了理解命令设计模式,我们应该理解相关的术语,例如客户端代码、命令、命令实现、调用者、接收者。

1. 命令(Command)是一个具有执行方法的接口,是整个约定(contract)的核心。

2. 客户端代码(Client)用于创建一个命令实现的实例,并将其与接收者(Receiver) 相关联。

3. 调用者(Invoker)知道命令执行响应的动作。

4. 命令的实现创建一个接收者和动作的绑定。

5. 接收者知道执行动作的真实的步骤。

命令模式的讨论

使用一个例子更容易理解上面的描述。我们考虑开发一个万能遥控器(universal remote)。我们的UniversalRemote有两个按钮,一个用于打开,一个用于关闭所关联的ConsumerElectronics

对于ConsumerElectronic我们有两个实现,TelevisionSoundSystemButton是一个动作的调用者。

OnCommand用于转换ConsumerElectronic的开关。当实例化OnCommand的时候需要设置接收者(receiver),在这里接收者是TelevisionSoundSystemUnversalRemote类持有所有的接收者并提供一个方法确定当前活动的接收者。

当创建一个调用者的实例的时候,一个具体的命令要作为参数传递进去。调用者并不知道怎样执行一个动作。它要做的就是履行Command的约定。调用者调用具体命令的execute方法。

命令模式的UML

 

命令模式的实现

Command.java

package com.designpatten.command;
/**
 * 命令接口
 * @author suifeng
 *
 */
public interface Command {
	void execute();
}


ConsumerElectronic.java

package com.designpatten.command;

/**
 * 调用者接口
 * @author suifeng
 *
 */
public interface ConsumerElectronic {
	void on();
	void mute();
}

 

OnCommand.java

package com.designpatten.command;

/**
 * "打开"命令的实现
 * @author suifeng
 *
 */
public class OnCommand implements Command {
	private ConsumerElectronic ce;
	
	public OnCommand(ConsumerElectronic ce) {
		super();
		this.ce = ce;
	}

	public void execute() {
		this.ce.on();
	}

}


MuteAllCommand.java

package com.designpatten.command;

import java.util.List;

/**
 * "关闭全部"命令的实现
 * @author Administrator
 *
 */
public class MuteAllCommand implements Command {
	private List<ConsumerElectronic> ceList;
	
	public MuteAllCommand(List<ConsumerElectronic> ceList) {
		super();
		this.ceList = ceList;
	}

	public void execute() {
		for (ConsumerElectronic ce : ceList) {
			ce.mute();
		}

	}

}


UniversalRemote.java

package com.designpatten.command;

/**
 * "万能遥控器类",用于获取活动的设备
 * @author suifeng
 *
 */
public class UniversalRemote {
	public static ConsumerElectronic getActiveElectronic()
	{
		return new Television();
	}
}


DemoCommandPatten.java

package com.designpatten.command;

import java.util.ArrayList;
import java.util.List;

/**
 * 测试实现
 * @author suifeng
 *
 */
public class DemoCommandPatten {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 创建一个当前活动的设备
		ConsumerElectronic ce = UniversalRemote.getActiveElectronic();
		// 封装一个命令
		Command onCommand = new OnCommand(ce);
		// 创建调用者
		Button button = new Button(onCommand);
		// 开始调用
		button.invoke();
		System.out.println("================华丽的分割线=============");
		ConsumerElectronic tv = new Television();
		ConsumerElectronic ss = new SoundSystem();
		
		List<ConsumerElectronic> ceList = new ArrayList<ConsumerElectronic>();
		ceList.add(tv);
		ceList.add(ss);
		
		// 封装命令
		Command muteCommand = new MuteAllCommand(ceList);
		// 创建调用者
		Button button2 = new Button(muteCommand);
		button2.invoke();
	}

}


 

命令模式的要点

1. 命令模式帮助实现调用者和接收者的解耦合,其中接收者知道怎样执行一个动作。

2. 命令模式可以帮助实现回调。

3. 增强了可扩展性,我们可以在不改变现有代码的基础上新增一个命令。

4. 命令模式定义了接收者和动作的绑定。

5. 一个命令应该能够实现重做和取消的功能。

JDK中的命令模式

java.lang.Runnablejavax.swing.Action都使用了命令模式。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值