最后是 调用者
→ 客户端通过与调用者交互来操作不同的命令对象。
public class Client { public static void main(String[] args) { // 实例化播放列表 List<Music> musics = new ArrayList<>(); musics.add(new Music("白雪公主", "")); musics.add(new Music("青蛙的愿望", "")); musics.add(new Music("驴和马", "")); musics.add(new Music("小青蛙的烦恼", "")); musics.add(new Music("三字经", "")); // 实例化接收者 IPlayer musicPlayer = new MusicPlayer(); // 实例化调用者,并传入具体命令实例 Invoker invoker = new Invoker(); invoker.setSetPlayListCommand(new SetPlayListCommand(musicPlayer)); invoker.setPlayCommand(new PlayCommand(musicPlayer)); invoker.setNextCommand(new NextCommand(musicPlayer)); invoker.setPreCommand(new PreCommand(musicPlayer)); invoker.setPauseCommand(new PauseCommand(musicPlayer)); // 测试调用 invoker.play(); invoker.setPlayList(null); invoker.setPlayList(musics); invoker.play(); invoker.next(); invoker.pre(); invoker.pre(); invoker.pause(); invoker.play(); invoker.next(); invoker.next(); invoker.next(); invoker.next(); invoker.next(); } }
代码运行结果如下:
网络异常,图片无法展示
|
代码很浅显易懂,涉及到的角色功能也有说,就不再复述了:
抽象命令、具体命令、抽象接收者、具体接收者、调用者
直接带出UML类图、使用场景和优缺点~
网络异常,图片无法展示
|
使用场景
- 不支持函数传递的编程语言,利用命令模式可以把函数当成对象使用;
- 请求调用者和接收者 解耦,不直接交互,调用者无需知道接收者是谁及如何操作;
- 围绕命令维度构建功能、自由组合相关命令、统计跟踪行为操作;
优点:
- 更松散的耦合,请求者无需知道执行者是谁,如何执行指令。
- 更动态的控制,将请求封装,可以动态进行参数化,队列化,日志化等操作。
- 命令可以复合,即一个命令可以由多个命令组合而成,又叫宏命令
- 更好的扩展性,因为命令发起者与执行者解耦,扩展新命令,只需实现新的命令对象;
- 为请求的撤销(Undo)和恢复(Redo)操作提供了一种设计和实现方案
缺点
- 不同接收者需要实现重复命令;
- 命令涉及对象变化时,可能导致不同的结果;
- 新增命令,对应的接收者都要新增命令实现,顺带也会影响接收者实现,不好维护;
以上内容就是本节的全部内容,谢谢~