命令模式的定义如下:
将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供撤销和恢复功能
命令模式的通用类图如下:
通过类图可以看到命令模式主要涉及到三个角色
- Receiver接收者角色,命令传到这里是应该被执行的
- Command命令模式,需要执行的命令都在这里定义
- Invoker调用者角色,接收到命令并执行命令
/**
* 抽象命令类
*
*/
public abstract class Command {
protected abstract void execute();
}
/**
* 命令的具体实现类
*
*/
public class ConcreteCommand extends Command {
private Reciver reciver;
public ConcreteCommand(Reciver reciver) {
this.reciver = reciver;
}
/**
* 命令的执行方法
*
* @see com.huashao.chapter.chapter15.ch01.Command#execute()
*/
@Override
protected void execute() {
reciver.action();
}
}
/**
* 接收者角色
*
*/
public class Reciver {
public void action() {
System.out.println("保证完成任务");
}
}
/**
* 执行者角色
*
*/
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}
public class Client {
public static void main(String[] args) {
// 创建接收者
Reciver reciver = new Reciver();
// 创建命令
Command command = new ConcreteCommand(reciver);
// 创建执行者
Invoker invoker = new Invoker(command);
// 执行请求
invoker.action();
}
}
命令模式的优点:
- 解耦或者说类见间解耦,调用者角色和接收者角色之间没有任何依赖,两个角色是完全独立的
- 高扩展性,命令类可以很容易的扩展而Invoker类和Client类不会受到影响
现在项目中有一个查询界面,查询分为两部分组成:下拉列表和输入框,首先用户需要从下拉列表中选择需要根据什么查询:订单号、退款号、账号等等,然后再输入框中输入要查询的号码需求叙述完毕,下面看看如何使用命令模式实现,类图如下:
public class CommandVO {
private String type;
private String value;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public interface Command {
public void query(CommandVO vo);
}
public class QueryService implements Command {
private OrderQueryDao orderQueryDao;
private RefundOrderQueryDao refundOrderQueryDao;
/**
* @param vo
* @see com.huashao.chapter.chapter15.ch03.Command#query(com.huashao.chapter.chapter15.ch03.CommandVO)
*/
@Override
public void query(CommandVO vo) {
// TODO Auto-generated method stub
if ("ORDERNO".equals(vo.getType())) {
orderQueryDao.findByOderNo(vo);
}
if ("REFUNDORDERNO".equals(vo.getType())) {
refundOrderQueryDao.queryByRefundOderNo(vo);
}
}
}
public class OrderQueryDao {
public void findByOderNo(CommandVO vo) {
System.out.println(vo.getType() + ":" + vo.getValue());
}
}
public void queryByRefundOderNo(CommandVO vo){
System.out.println(vo.getType()+":"+vo.getValue());
}
}
public class QueryAction {
private Command command;
public void findByCondi(CommandVO vo) {
command.query(vo);
}
}