概述
- 定义:将来自客户端的请求传入一个对象,从而使你可用不同的请求对客户进行参数化。用于“行为请求者”与“行为实现者”解耦,可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素
- 适用场景:
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
- 系统需要在不同的时间指定请求、将请求排队和执行请求。
- 系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
- 系统需要将一组操作组合在一起,即支持宏命令
实现
// 命令接受者
public class MP3Player {
public void play() {
System.out.println("开始播放");
}
public void stop() {
System.out.println("停止播放");
}
public void next() {
System.out.println("切换到下一首");
}
}
// 命令接口
public interface Command {
void execute();
}
// 播放命令
class CommandPlay implements Command {
private MP3Player player;
public CommandPlay(MP3Player player) {
this.player = player;
}
@Override
public void execute() {
player.play();
}
}
// 停止命令
class CommandStop implements Command {
private MP3Player player;
public CommandStop(MP3Player player) {
this.player = player;
}
@Override
public void execute() {
player.stop();
}
}
// 下一首命令
class CommandNext implements Command {
private MP3Player player;
public CommandNext(MP3Player player) {
this.player = player;
}
@Override
public void execute() {
player.next();
}
}
// Command Invoker
public class Controller {
private Command cPlay;
private Command cStop;
private Command cNext;
public Controller(Command cPlay, Command cStop, Command cNext) {
this.cPlay = cPlay;
this.cStop = cStop;
this.cNext = cNext;
}
public void play() {
cPlay.execute();
}
public void stop() {
cStop.execute();
}
public void next() {
cNext.execute();
}
}
// 客户端
public class Client {
public static void main(String[] args) throws Exception {
MP3Player player = new MP3Player();
Command cp = new CommandPlay(player);
Command cs = new CommandStop(player);
Command cn = new CommandNext(player);
Controller ctrl = new Controller(cp, cs, cn);
ctrl.play();
ctrl.next();
ctrl.stop();
}
}
实际应用
java.util.concurrent.ThreadPoolExecutor
- ThreadPoolExecutor相当于调用者,可通过submit、shutdown等方法执行命令
- ThreadPoolExecutor中有一个BlockingQueue类型的成员变量,相当于命令队列
- Runnable相当于命令,但一般情况下接受者的角色也由Runnable来承担