一、命令模式的定义
命令是对命令的封装,每一个命令都是一个操作,请求方发出请求,接收方接收请求,并执行操作。命令模式解耦了请求方和接收方,命令模式属于行为型模式
二、命令模式的uml图和通用写法
uml
通用写法
/**
* 功能:命令的抽象
*/
public interface ICommand {
void execute();
}
/**
* 功能:具体的命令
*/
public class ConcreteCommand implements ICommand{
Receiver receiver = new Receiver();
@Override
public void execute() {
receiver.action();
}
}
/**
* 功能:命令接收者
*/
public class Receiver {
public void action() {
System.out.println("具体执行");
}
}
/**
* 功能:命令请求者
*/
public class Invoker {
private ICommand iCommand;
public Invoker(ICommand iCommand) {
this.iCommand = iCommand;
}
public void action() {
iCommand.execute();
}
}
public class Tests {
public static void main(String[] args) {
ICommand command = new ConcreteCommand();
Invoker invoker = new Invoker(command);
invoker.action();
}
}
命令模式中的4个角色:
- 接收者角色(Receiver):负责具体执行一个请求
- 命令角色(ICommand):定义需要执行的所有命令行为
- 具体的命令角色(ConcreteCommand):内部维护一个Receiver
- 请求者角色(Invoker):接收客户端的命令,并执行命令
三、遥控操作电视的例子
uml
/**
* 功能:操作命令
*/
public interface Command {
void execute();
}
/**
* 功能:打开电视机
*/
public class OpenCommand implements Command{
private TV tv = new TV();
@Override
public void execute() {
tv.open();
}
}
/**
* 功能:换台
*/
public class ChangeCommand implements Command{
private TV tv = new TV();
@Override
public void execute() {
tv.change();
}
}
/**
* 功能:关闭电视机
*/
public class CloseCommand implements Command{
private TV tv = new TV();
@Override
public void execute() {
tv.close();
}
}
package com.kangping.command.lizi;
import java.util.ArrayList;
import java.util.List;
/**
* 功能:遥控器
*/
public class Control {
public List<Command> commands = new ArrayList<>();
public Control(Command command) {
commands.add(command);
}
public Control(List<Command> commands) {
this.commands.addAll(commands);
}
public void action() {
commands.forEach(e -> e.execute());
}
}
/**
* 功能:电视机
*/
public class TV {
public void open() {
System.out.println("打开电视机");
}
public void change() {
System.out.println("切换电视机");
}
public void close() {
System.out.println("关闭电视机");
}
}
/**
* 功能:
*/
public class Tests {
public static void main(String[] args) {
Command command = new OpenCommand();
Command changeCommand = new ChangeCommand();
Command closeCommand = new CloseCommand();
List list = new ArrayList<>();
list.add(command);
list.add(changeCommand);
list.add(closeCommand);
Control control = new Control(list);
control.action();
}
}
四、java 源码中的使用
命令模式在jdk中的使用
public interface Runnable {
public abstract void run();
}
Runnable相当于命令的抽象。实际上调用线程的start以后,就有资格去抢cpu的资源,不要去写获取cpu资源的逻辑,抢到cpu资源以后执行run方法中的内容。Runnable接口把用户请求和cpu执行进行解耦。
五、优点和缺点
优点:
- 通过引入命令的抽象接口,实现了命令请求与实现的解耦
- 扩展性良好,可以很容易的增加新命令
缺点:
1.命令类可能过多