设计模式之-----命令模式

今天继续学习设计模式的命令模式,命令模式在生活中算是比较常见的,比如在《大话设计模式》中,“命令模式”一节中举得烤羊肉串的例子,小摊贩烤的羊肉串,由于没有记录,导致人多的时候,很容易忘记哪个顾客要的什么,要了多少,是否给钱了,要不要辣椒,这些都很容易记混的。而在一个正式的店面中,有专门的服务员负责记录,服务员通知后厨去烤羊肉串,顾客不必与厨师亲自打交道,这就体现了一个命令模式的特点,将命令请求者与命令执行者彻底解耦,当然这只是其中一个好处。

在比如电视遥控器的例子,遥控器封装了一系列的功能,用户只要知道这些按键是干嘛的,不需要知道内部是怎么运作的,就可以操作电视开关,换台等操作。

以下是官方的解释:命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

我们举个例子,我们都用过记事本,记事本有增加记录,删除记录,撤销操作等等,我们就用命令模式来实现这个功能,来看实现代码

这是包结构

首先是记事本

package com.command.receiver;

/**
 * 记事本类,负责执行具体的操作
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public class NotePad {

	/**
	 * 在记事本中增加一条记录
	 */
	public void addThing(){
		System.out.println("增加一条记录");
	}
	
	/**
	 * 在记事本中删除一条记录
	 */
	public void removeThing(){
		System.out.println("删除一条记录");
	}
	
	/**
	 * 对当前编辑进行撤销操作
	 */
	public void backOut(){
		System.out.println("撤销当前操作");
	}
}

然后是命令的抽象接口

package com.command.command;

/**
 * 命令的抽象接口
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public interface Command {

	/**
	 * 执行命令
	 */
	public void execute();
}

具体的命令类

package com.command.concrete.command;

import com.command.command.Command;
import com.command.receiver.NotePad;

/**
 * 增加记录的命令
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public class AddThingCommand implements Command{

	//具体操作类的对象
	private NotePad notePad;

	public AddThingCommand(NotePad notePad) {
		super();
		this.notePad = notePad;
	}

	/**
	 * 增加记录的命令执行的入口
	 */
	public void execute() {
		//调用真正的操作类来实现具体功能
		notePad.addThing();
	}

}

package com.command.concrete.command;

import com.command.command.Command;
import com.command.receiver.NotePad;

/**
 * 删除记录的命令
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public class RemoveThingCommand implements Command{

	//具体操作类的对象
	private NotePad notePad;

	public RemoveThingCommand(NotePad notePad) {
		super();
		this.notePad = notePad;
	}

	/**
	 * 删除记录的命令执行的入口
	 */
	public void execute() {
		//调用真正的操作类来实现具体功能
		notePad.removeThing();
	}

}

package com.command.concrete.command;

import com.command.command.Command;
import com.command.receiver.NotePad;

/**
 * 撤销操作的命令
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public class BackOutCommand implements Command{

	//具体操作类的对象
	private NotePad notePad;

	public BackOutCommand(NotePad notePad) {
		super();
		this.notePad = notePad;
	}

	/**
	 * 撤销操作命令执行的入口
	 */
	public void execute() {
		//调用真正的操作类来实现具体功能
		notePad.backOut();
	}

}

然后就是请求者,这里请求者是键盘

package com.command.invoker;

import com.command.command.Command;

/**
 * 请求者,这里由键盘扮演
 * 对于记事本而言,只有键盘请求它才能做出相应,如果我们对它说句话,记事本是不会有反应的
 * 所以对于记事本,真正的请求者是键盘,而人类是去操作键盘的
 * 记事本不会在意是谁敲的键盘,它只是负责响应键盘请求
 * @author ZHENGWEI
 * @date 2015-8-10
 */
public class KeyBoard {

	private Command addThingCommand;
	private Command removeThingCommand;
	private Command backOutCommand;
	
	public void setAddThingCommand(Command addThingCommand) {
		this.addThingCommand = addThingCommand;
	}
	public void setRemoveThingCommand(Command removeThingCommand) {
		this.removeThingCommand = removeThingCommand;
	}
	public void setBackOutCommand(Command backOutCommand) {
		this.backOutCommand = backOutCommand;
	}
	
	/**
	 * 增加的方法
	 */
	public void add(){
		addThingCommand.execute();
	}
	
	/**
	 * 删除的方法
	 */
	public void remove(){
		removeThingCommand.execute();
	}
	
	/**
	 * 撤销的方法
	 */
	public void back(){
		backOutCommand.execute();
	}
}

最后是测试类

package com.command.main;

import com.command.command.Command;
import com.command.concrete.command.AddThingCommand;
import com.command.concrete.command.BackOutCommand;
import com.command.concrete.command.RemoveThingCommand;
import com.command.invoker.KeyBoard;
import com.command.receiver.NotePad;

public class CommandMain {

	public static void main(String[] args) {
		NotePad notePad = new NotePad();
		
		Command add = new AddThingCommand(notePad);
		Command remove = new RemoveThingCommand(notePad);
		Command back = new BackOutCommand(notePad);
		
		KeyBoard keyBoard = new KeyBoard();
		keyBoard.setAddThingCommand(add);
		keyBoard.setRemoveThingCommand(remove);
		keyBoard.setBackOutCommand(back);
		
		keyBoard.add();
		keyBoard.remove();
		keyBoard.back();
	}

}

然后来看看结果


最后引用ID为jason0539博客的总结

http://blog.csdn.net/jason0539/article/details/45110355


优点
1.降低对象之间的耦合度。
2.新的命令可以很容易地加入到系统中。
3.可以比较容易地设计一个组合命令。
4.调用同一方法实现不同的功能

缺点
使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用情况
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起,即支持宏命令。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值