本文共 4604 字,大约阅读时间需要 15 分钟。
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以支持可撤销的操作。
命令模式的角色
1. 客户端角色(Client):创建一个具体命令(ConcreteCommand)对象并确定其接收者。 2. 命令角色(Command):声明一个给所有命令类的抽象接口。 3. 具体命令角色(ConcreteCommand):定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法叫做执行方法。 4. 请求者角色(Invoker):负责调用命令对象执行请求,相关的方法叫做行动方法。 5. 接收者角色(Receiver):负责具体实施和执行一个请求。任何一个类都可以称为接收者,实施和执行请求的方法叫做行动方法。举个简单例子(录音机有播音Play,倒带Rewind和停止Stop功能)
1 接收者角色public class AudioPlayer{ public void play() { System.out.println("Play"); } public void rewind() { System.out.println("Rewind"); } public void stop() { System.out.println("Stop"); }}
2 抽象命令角色
public interface Command{ public void execute();}
3 具体命令角色
public class PlayCommand implements Command{ private AudioPlayer myAudio; public PlayCommand(AudioPlayer audioPlayer) { this.myAudio = audioPlayer; } @Override public void execute() { myAudio.play(); }}public class RewindCommand implements Command{ private AudioPlayer myAudio; public RewindCommand(AudioPlayer audioPlayer) { this.myAudio = audioPlayer; } @Override public void execute() { this.myAudio.rewind(); }}public class StopCommand implements Command{ private AudioPlayer myAudio; public StopCommand(AudioPlayer audioPlayer) { this.myAudio = audioPlayer; } @Override public void execute() { this.myAudio.stop(); }}
4 请求这角色(由按键扮演)
public class Keypad{ private Command playCommand; private Command rewindCommand; private Command stopCommand; public void setPlayCommand(Command playCommand) { this.playCommand = playCommand; } public void setRewindCommand(Command rewindCommand) { this.rewindCommand = rewindCommand; } public void setStopCommand(Command stopCommand) { this.stopCommand = stopCommand; } public void play() { playCommand.execute(); } public void rewind() { rewindCommand.execute(); } public void stop() { stopCommand.execute(); }}
5 客户端角色
AudioPlayer audioPlayer = new AudioPlayer(); Command playCommand = new PlayCommand(audioPlayer); Command rewindCommand = new RewindCommand(audioPlayer); Command stopCommand = new StopCommand(audioPlayer); Keypad keypad = new Keypad(); keypad.setPlayCommand(playCommand); keypad.setRewindCommand(rewindCommand); keypad.setStopCommand(stopCommand); keypad.play(); keypad.rewind(); keypad.stop();
输出:
PlayRewindStop
所谓的宏命令简单点说就是包含多个命令的命令,是一个命令的组合。
修改上面的案例,当客户端需要一个记录的工,可以把一个一个命令记录下来,再在任何需要的时候重新把这些记录下来的命令一次执行,这就是所谓的宏命令功能。 1 系统需要一个代表宏命令的接口,以定义出具体宏命令所需要的接口public interface MacroCommand extends Command{ public void add(Command cmd); public void remove(Command cmd);}
2 具体的宏命令MarcoAudioCommand类负责把个别的命令合成宏命令
public class MacroAudioCommand implements MacroCommand{ private ListcommandList = new ArrayList (); @Override public void execute() { for(Command cmd: commandList) { cmd.execute(); } } @Override public void add(Command cmd) { commandList.add(cmd); } @Override public void remove(Command cmd) { commandList.remove(cmd); }}
3 客户端
AudioPlayer audioPlayer = new AudioPlayer(); Command playCommand = new PlayCommand(audioPlayer); Command rewindCommand = new RewindCommand(audioPlayer); Command stopCommand = new StopCommand(audioPlayer); MacroCommand marco = new MacroAudioCommand(); marco.add(playCommand); marco.add(rewindCommand); marco.add(stopCommand); marco.execute();
适用场景
在下面的情况下应当考虑应用命令模式:优缺点
优点:缺点:
JDK中的命令模式
java.lang.Runnable javax.swing.Action
参考资料
1. 2. 3.