欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

命令模式

程序员文章站 2022-05-26 08:39:25
...

1.命令模式的定义

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

2.命令模式的结构和说明


命令模式


  • Command: 定义命令的接口,生命执行的方法
  • ConcreteCommand:  命令接口实现对象,是“虚”的实现;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
  • Receiver:   接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现的相应功能。
  • Invoker:  要求命令对象执行请求,通常 会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令执行相应操作的地方。
  • Client:  创建具体的命令对象,并且设置命令对象的接收者。

相关代码如下:

  1. 接口的定义
/**
 * 命令接口,声明执行的操作
 * 
 * @author Administrator
 *
 */
public interface Command {

	/**
	 * 执行命令对应的操作
	 */
	public void execute();

}

2.具体的命令实现对象

/**
 * 具体的命令 实现对象
 * 
 * @author Administrator
 *
 */
public class ConcreteCommand implements Command {

	/**
	 * 持有相应的接收者对象
	 */
	private Receiver receiver;

	/**
	 * 命令对象可以有自己的状态
	 */
	private String state;

	public ConcreteCommand(Receiver receiver) {
		this.receiver = receiver;
	}

	@Override
	public void execute() {
		// 通常会转调接收者对象的相应方法,让接收者来真正执行 功能
		receiver.action();

	}

}

3. 接收者对象

/**
 * 接收者对象
 * 
 * @author Administrator
 *
 */
public class Receiver {

	/**
	 * 真正执行命令相应的操作
	 */
	public void action() {

		// 真正执行命令操作的功能代码
	}

}

4.Invoker对象

 * 调用者
 * 
 * @author Administrator
 *
 */
public class Invoker {
	private Command command = null;

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

	/**
	 * 要求命令执行要求
	 */
	public void runCommand() {
		// 调用命令对象的执行方法
		command.execute();
	}

}


5.Client 的实现

public class Client {

	public static void main(String[] args) {
		// 创建接收者
		Receiver receiver = new Receiver();
		// 创建命令对象,设定它的接收者
		Command command = new ConcreteCommand(receiver);
		// 创建Invoker,把命令对象设置进去
		Invoker invoker = new Invoker();
		invoker.setCommand(command);

		invoker.runCommand();

	}

}


使用命令模式实现电脑开机的场景:

  • 机箱上的按钮就相当于是命令对象
  • 机箱相当于是Invoker
  • 主板相当于接收者 对象
  • 命令对象持有一个接收者对象,就相当于给机箱的按钮连上一根连接线
  • 当机箱上的按钮被按下的时候,机箱就把这个命令通过连接线发送出去

主板类才是真正实现开机功能的地方,是真正执行命令的地方,也就是“接收者”。命令的实现对象,其实是个“虚”的实现,就如同那根连接线.

  使用命令模式来实现示例的结构如下图

  • 定义主板接口类
/**
 * 主板的接口
 * 
 * @author Administrator
 *
 */
public interface MainBorderApi {
	/**
	 * 主板具有开机的功能
	 */
	public void open();

}
  • 定义主板实现类
/**
 * 技嘉主板类,开机命令的真正实现者,在Command模式中充当Receiver
 * 
 * @author Administrator
 *
 */
public class GigaMainBoard implements MainBorderApi {

	/**
	 * 真正开机命令的实现
	 */
	@Override
	public void open() {
		System.out.println("技嘉主板现在正在开机摸清稍后");
		System.out.println("接通电源.................");
		System.out.println("设备检查..................");
		System.out.println("装载系统...................");
		System.out.println("机器正常运转起来...............");
		System.out.println("机器已经正常打开,请操作...........");

	}

}
  • 定义命令接口和命令的实现

    对于客户来说,开机就是按下按钮,别的什么都不想做,把用户的这个动作抽象一下,就相当于客户发出一个命令或者请求,其他的客户就不关心了。为描述客户的命令,现在定义出一个命令的接口,里面只有一个方法,那就是执行。示例代码如下;

/**
 * 命令接口,声明执行的操作
 * 
 * @author Administrator
 *
 */
public interface Command {

	/**
	 * 执行命令对应的操作
	 */
	public void execute();

}

/**
 * 开机命令的实现,实现Command接口 持有开机命令的真正实现,通过调用接收者的方法来实现命令
 * 
 * @author Administrator
 *
 */
public class OpenCommand implements Command {
	// 持有真正实现命令的接收者---主板对象
	private MainBorderApi mainBoard;

	public OpenCommand(MainBorderApi mainBoard) {

		this.mainBoard = mainBoard;
	}

	@Override
	public void execute() {
		// 对于命令对象,根本不知道如何开机,会转调主板对象
		// 让主板去完成开机的功能
		this.mainBoard.open();

	}

}
  • 提供机箱

  客户需要操作按钮,按钮是放置在机箱之上的,所以需要把机箱也定义出来。示例代码如下:

/**
 * 机箱对象,本身有按钮,持有按钮对应的命令对象
 * 
 * @author Administrator
 *
 */
public class Box {

	// 开机命令对象
	private Command command;

	public Box(Command command) {
		super();
		this.command = command;
	}

	/**
	 * 提供给客户使用,接收并响应用户请求,相当于按钮被按下出发的方法
	 */
	public void openButtonPresses() {
		// 按下按钮,执行命令
		this.command.execute();
	}

}
  • 客户使用按钮
public class Client {
	public static void main(String[] args) {
		// 1.把命令和真正的实现结合起来,相当于组装机器
		// 把机箱桑按钮的联系那插接到主板上行
		MainBorderApi mainBoard = new GigaMainBoard();
		OpenCommand openCommand = new OpenCommand(mainBoard);

		// 2.为机箱上的按钮设置对应的命令,让按钮知道该干什么

		Box box = new Box(openCommand);

		box.openButtonPresses();
	}

}

结果如下:

命令模式



相关标签: 命令模式