# 设计模式之----命令模式
来源:互联网 发布:网络维护基础知识 编辑:程序博客网 时间:2024/06/08 09:10
一、背景
该模式出现是为了解决一些问题:解耦,以达到对修改封闭,对扩展开放的原则(开闭原则);命令组合实现功能。
二、定义
将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日子,以及支持撤销的操作。
本例以录音机播放和暂停为例:
普通模式:按下键盘,调用录音机去播放或者暂停(需要写不同的分支,耦合度高,扩展时需要直接改动这部分逻辑)
命令模式:按下键盘时,将不同的操作封装为不同的命令对象,在命令对象中调用录音机去播放或者暂停,而键盘只需要去请求不同的操作命令对象执行即可,这样就使请求者(键盘)和执行者(录音机)实现了松耦合的结构。
三、命令模式中的角色
1. 客户端角色
创建一个具体命令,并制定其接收者。(例子中的用户)
2. 抽象命令角色
所有命令的抽象接口,抽象执行方法。
3. 具体命令角色
持有接受者角色的引用,实现抽象命令接口的执行方法,并调用接受者执行具体操作。(例子中的播放、暂停命令)
4. 请求者角色
持有命令角色,定义不同的请求方法,对应执行不同的命令。(例子中的键盘)
5. 接受者角色
负责接收和具体执行命令。(录音机)
四、简单代码实现
1. 创建接受者
/** * 录音机:接受者,执行具体的命令 * * Created by rytong on 2017/10/25. */public class AudioPlayer { private static final String TAG = AudioPlayer.class.getSimpleName(); // 播放 public void play(){ Log.e(TAG,"正在播放..."); } // 暂停 public void pause(){ Log.e(TAG,"已经暂停"); }}
2. 创建抽象命令接口
/** * 抽象命令接口 * * Created by rytong on 2017/10/25. */public interface CommadInterface { public void excute();}
3. 创建具体的命令角色
/** * 具体播放命令,持有接收者角色 * * Created by rytong on 2017/10/25. */public class PlayCommand implements CommadInterface { private AudioPlayer audioPlayer; public PlayCommand(AudioPlayer audioPlayer) { this.audioPlayer = audioPlayer; } @Override public void excute() { audioPlayer.play(); }}
4. 创建请求者
/** * 录音机按键:请求者角色,持有具体命令 * * Created by rytong on 2017/10/25. */public class AudioKeyboard { private CommadInterface playCommand; private CommadInterface pauseCommand; public void setPlayCommand(CommadInterface playCommand) { this.playCommand = playCommand; } public void setPauseCommand(CommadInterface pauseCommand) { this.pauseCommand = pauseCommand; } //播放 public void play(){ playCommand.excute(); } //暂停 public void pause(){ pauseCommand.excute(); }}
5. 客户端实现播放和暂停
//客户端//创建一个接受者AudioPlayer audioPlayer = new AudioPlayer();//创建具体的命令,制定接受者PauseCommand pauseCommand = new PauseCommand(audioPlayer);PlayCommand playCommand = new PlayCommand(audioPlayer);//创建请求者AudioKeyboard audioKeyboard = new AudioKeyboard();audioKeyboard.setPauseCommand(pauseCommand);audioKeyboard.setPlayCommand(playCommand);//请求者执行对应命令audioKeyboard.play();audioKeyboard.pause();
6. 具体执行结果
10-25 10:36:37.182 23772-23772/com.commandpattern E/AudioPlayer: 正在播放... 10-25 10:36:37.182 23772-23772/com.commandpattern E/AudioPlayer: 已经暂停
五、应用场景
- 当某些操作需要对行为进行记录,撤销等操作时可以采用;
- 系统设计时需要这种松耦合结构时;
- 系统需要不同命令组合实现功能时。
例子:线程的执行(省略了接收者,直接在具体命令中处理具体操作),简单代码 如下:
new Thread(new Runnable() { @Override public void run() { //dosomething } }).start();
六、优点
- 更松散的耦合:调用者不需要哦知道内部具体做了什么处理,只知道结果。
- 更动态的控制,可以把不同的命令组装起来,动态执行(比如总共有20个命令,不同组合可以实现不同的效果,这样会比较灵活)
- 扩展性好,只需要扩展新的命令,无需修改原有的逻辑。
七、缺点
如果系统比较庞大时,每个命令都需要编写一个新的类,这样系统会看起来非常臃肿;
阅读全文
0 0
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之--命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之--命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之命令模式
- 设计模式之 命令模式
- J2EE分布式架构 dubbo+springmvc+mybatis+ehcache+redis分布式架构
- shell基础
- 第八周【项目2
- Linux 基础命令(二)
- CSS特殊字符表
- # 设计模式之----命令模式
- angular4 模块懒加载
- MQTT协议之订阅及发布(使用paho-mqtt-client或mqttv3实现)
- 网络请求数据 Banner轮播
- MemoryModule阅读与PE文件解析(一)
- uml 构件
- charles 学习笔记之代理http,https请求
- 属性动画抛物线
- bzoj 3341: [Ceoi2013]adriatic