JAVA设计模式——命令模式
2018-01-29 11:04
197 查看
命令模式,又称为行动(Action)模式、交易(Transaction)模式,是一种行为型设计模式。命令模式的思想是:把一个请求或者操作封装到一个对象中,允许系统使用不同的请求把客户端参数化,从而实现对请求排队或者记录请求日志、提供命令的撤销和恢复功等能。
命令模式涉及5个角色:
客户(Client):创建一个具体命令对象并确定其接收者。
抽象命令(Command):声明了一个给所有具体命令类的抽象接口。
具体命令(Concrete Command):定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。
请求者(Invoker):负责调用命令对象执行请求。
接收者(Receiver):负责具体实施和执行一个请求。任何一个类都可以成为接收者。
结构图:
![](https://img-blog.csdn.net/20180129100037955?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXJrb2hha3U=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
具体代码实现:
运行结果:
hey Geek!!
可以看到请求者和接收者是松耦合的,因此要增删命令很容易就可以实现。
下面提供一个例子,一个录音机,有
运行结果:
playing…
stopped!!
rewinding…
playing…
stopped!!
==========
playing…
stopped!!
rewinding…
stopped!!
命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。
命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。
由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。
命令模式涉及5个角色:
客户(Client):创建一个具体命令对象并确定其接收者。
抽象命令(Command):声明了一个给所有具体命令类的抽象接口。
具体命令(Concrete Command):定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。
请求者(Invoker):负责调用命令对象执行请求。
接收者(Receiver):负责具体实施和执行一个请求。任何一个类都可以成为接收者。
结构图:
具体代码实现:
// 接收者 public class Receiver { public void action() { System.out.println("hey Geek!!"); } } // 抽象命令 public interface Command { void execute(); } // 具体命令 public class ConcreteCommand implements Command { private Receiver receiver; // 持有一个接收者引用 public ConcreteCommand(Receiver receiver) { this.receiver = receiver; } @Override public void execute() { receiver.action(); } } // 请求者 public class Invoker { private Command command; // 持有一个命令引用 public Invoker(Command command) { this.command = command; } public void action() { command.execute(); } } // 客户 public class Client { private Invoker invoker; // 持有一个请求者引用 public void method() { Receiver receiver = new Receiver(); Command command = new ConcreteCommand(receiver); // 指定接收者 invoker = new Invoker(command); // 指定命令 invoker.action(); // 执行 } } // 测试 class CommandTest { public static void main(String[] args) { Client client = new Client(); client.method(); } }
运行结果:
hey Geek!!
可以看到请求者和接收者是松耦合的,因此要增删命令很容易就可以实现。
下面提供一个例子,一个录音机,有
play,
rewind,
stop三个按键,分别对应播放、倒带、停止三个功能。另外还有个一个宏命令功能。
// 录音机,相当于接收者,实际上的功能拥有者 public class AudioPlayer { public void play() { System.out.println("playing..."); } public void rewind() { System.out.println("rewinding..."); } public void stop() { System.out.println("stopped!!"); } } // 抽象命令 public interface Command { void execute(); } // 播放命令 public class PlayCommand implements Command { private AudioPlayer audioPlayer; public PlayCommand(AudioPlayer audioPlayer) { this.audioPlayer = audioPlayer; } @Override public void execute() { audioPlayer.play(); } } // 倒带命令 public class RewindCommand implements Command { private AudioPlayer audioPlayer; public RewindCommand(AudioPlayer audioPlayer) { this.audioPlayer = audioPlayer; } @Override public void execute() { audioPlayer.rewind(); } } // 停止命令 public class StopCommand implements Command { private AudioPlayer audioPlayer; public StopCommand(AudioPlayer audioPlayer) { this.audioPlayer = audioPlayer; } @Override public void execute() { audioPlayer.stop(); } } // 按键,相当于请求者 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(); } } // 抽象宏 public interface Macro { void add(Command command); // 添加命令 void removeLast(); // 删除最后添加的命令 void execute(); // 依次执行列表中的命令 } // 具体宏 public class MacroCommand implements Macro { private List<Command> list = new ArrayList<>(); // 持有一个命令列表引用 @Override public void add(Command command) { list.add(command); } @Override public void removeLast() { list.remove(list.size()-1); } @Override public void execute() { list.forEach(Command::execute); } } // 用户 public class User { private AudioPlayer audioPlayer = new AudioPlayer(); private Command playCommand = new PlayCommand(audioPlayer); private Command rewindCommand = new RewindCommand(audioPlayer); private Command stopCommand = new StopCommand(audioPlayer); // 方法一:使用普通的命令模式执行请求 public void method1() { Keypad keypad = new Keypad(); keypad.setPlayCommand(playCommand); keypad.setRewindCommand(rewindCommand); keypad.setStopCommand(stopCommand); keypad.play(); keypad.stop(); keypad.rewind(); keypad.play(); keypad.stop(); } // 方法二:使用宏的方式执行请求 public void method2() { Macro macro = new MacroCommand(); macro.add(playCommand); macro.add(stopCommand); macro.add(rewindCommand); macro.add(playCommand); macro.removeLast(); macro.add(stopCommand); macro.execute(); } } // 测试 class CommandTest { public static void main(String[] ar a676 gs) { User user = new User(); user.method1(); System.out.println("=========="); user.method2(); } }
运行结果:
playing…
stopped!!
rewinding…
playing…
stopped!!
==========
playing…
stopped!!
rewinding…
stopped!!
总结
命令模式使得发起命令的对象——客户,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。
命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。
由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。
相关文章推荐
- java设计模式_命令模式
- java设计模式之Command(菜单命令)
- java设计模式_命令模式
- java设计模式之命令模式Command
- JAVA设计模式之命令模式
- Java设计模式之命令模式
- Java设计模式(16)--命令
- JAVA设计模式—命令模式(Command)
- Java设计模式之命令模式
- java 设计模式学习笔记十二 command命令设计模式
- Java设计模式八:命令模式(Command)
- Java实用设计模式:Command(命令模式)
- 设计模式(十四)----- 命令模式(Command)----(JAVA版)
- JAVA设计模式之命令模式
- JAVA设计模式九--Command(命令模式)
- java 设计模式-行为模式之命令模式
- Java设计模式 Design Pattern:命令模式 Command Pattern
- java设计模式_命令模式 两个不同风格的实现
- Java设计模式 Design Pattern:命令模式 Command Pattern
- Java设计模式——命令模式