-- 命令模式 请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
简单来说: 将命令抽象为对象Object,建一个合适的对象(计算机),客户端(人)往合适的对象(计算机)输入命令,合适的对象又把命令传给相应的对象(Invoker),最后由该(Invoker)对象执行命令。
人(客户端) -> Receiver计算机(合适的对象) -> 上下左右按键(命令) -> Invoker(真正执行命令的对象)
一、使用场景
在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。
二、模式结构
引用官方结构图:
组成(角色) | 作用 |
---|---|
Command (抽象命令) | 提供execute()的抽象方法 |
ConcreteCommand (具体命令对象) | 实现具体命令 |
Receiver(接收者) | 负责接收命令,里面有命令的行为方法 Action() |
Invoker (调用者) | 真正执行命令的对象 |
二、优缺点
优点:
- 降低了系统耦合度。
- 新的命令可以很容易添加到系统中去。
缺点:
- 使用命令模式可能会导致某些系统有过多的具体命令类。
三、栗子 《拳皇命令》
1、Command (抽象命令)
package com.behavior.command;
/**
* @description: 命令
* @author: ziHeng
* @create: 2018-08-15 18:21
**/
public abstract class Command {
protected Computer computer;
public Command(Computer computer) {
this.computer = computer;
}
//计算机执行
abstract String execute();
}
2、ConcreteCommand (具体命令对象)
(1)、键盘 ↑ 键命令
package com.behavior.command;
/**
* @description: 上键 - 按钮
* @author: ziHeng
* @create: 2018-08-15 18:23
**/
public class UpCommand extends Command{
public UpCommand(Computer computer) {
super(computer);
}
@Override
public String execute() {
//计算机执行
return computer.upKey();
}
}
(2)、键盘 ↓ 键命令
package com.behavior.command;
/**
* @description: 下键 - 按钮
* @author: ziHeng
* @create: 2018-08-15 18:23
**/
public class DownCommand extends Command{
public DownCommand(Computer computer) {
super(computer);
}
@Override
public String execute() {
//计算机执行
return computer.downKey();
}
}
3、Receiver(命令接收者) - 电脑
package com.behavior.command;
import lombok.Data;
/**
* @description: 电脑 - receiver
* @author: ziHeng
* @create: 2018-08-15 18:22
**/
@Data
public class Computer {
private String name;
public Computer(String name) {
this.name = name;
}
//action()
public String upKey(){
return "上";
}
public String downKey(){
return "下";
}
}
4、Invoker (调用者)
-- 真正的执行命令对象,或对命令进行记录
package com.behavior.command;
import java.util.ArrayList;
import java.util.List;
/**
* @description: 调用者 - 真正执行命令的对象
* @author: ziHeng
* @create: 2018-08-15 19:10
**/
public class Invoker {
private List<Command> commandList;
public Invoker() {
this.commandList = new ArrayList<>();
}
//添加命令
public void addCommand(Command command){
commandList.add(command);
}
//删除命令
public void deleteCommand(Command command){
commandList.remove(command);
}
//执行所有命令
public void executeAllCommand(){
//对行为进行记录
StringBuilder combineKey = new StringBuilder();
for (Command command:commandList){
//命令执行
combineKey.append(command.execute());
}
//对执行过的命令进行判断
String combineString = combineKey.toString();
switch (combineString){
case "上上下下":
System.out.println("计算机名:"+commandList.iterator().next().computer.getName());
System.out.println(combineString+" - 发动联合技:背摔");break;
case "上下上下":
System.out.println("计算机名:"+commandList.iterator().next().computer.getName());
System.out.println(combineString+" - 发动联合技:洞洞波");break;
default:
System.out.println("该按键组合没有联合技");
}
//清除命令
commandList.clear();
}
}
调用Test:
package com.behavior.command;
/**
* @description: 命令模式
* @author: ziHeng
* @create: 2018-08-15 18:07
**/
public class CommandTest {
public static void main(String[] args) {
//计算机
Computer computer = new Computer("银河一号");
//初始化调用者
Invoker invoker = new Invoker();
//初始化命令
Command upCommand = new UpCommand(computer);
Command downCommand = new DownCommand(computer);
//客户端输入命令
invoker.addCommand(upCommand);
invoker.addCommand(downCommand);
invoker.addCommand(upCommand);
invoker.addCommand(downCommand);
//执行命令
invoker.executeAllCommand();
}
}
控制台展示: