[学习笔记]设计模式[5]-{命令模式}
来源:互联网 发布:mac 界面英文变中文版 编辑:程序博客网 时间:2024/05/16 12:22
设计模式
当我们在开发系统时,可能会遇到这样的问题:我需要对一些互无关联的类进行相似的操作,而且这些操作还有可能在未来有变化,需要这个操作的类可能会增加。
想想我们的第一个设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
在这种场景下,类可能是不需要变化的,但是可能会发生变化的是对类的”操作”。那么我们要怎么把”操作”独立出来呢,这里的命令模式就可以很好的解决这个问题。
命令模式
先从正式的定义开始:
命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
定义中的“请求”就可以看做是对对象进行的操作的请求或者对类进行更改的请求。
我们拿书上的例子来理解命令模式:你需要实现一个遥控器的类,这个类需要对一些家电,例如电视类、壁灯类、风扇类等等进行操作。下面是其中的一些类:
public class TV(){ public void on(){...} public void off(){...} public void setChannel(int i){...} public void setVolume(int i){...}}
public class CeilingLight(){ public void on(){...} public void off(){...} public void dim(){...}}
public class CeilingFan(){ public void on(){...} public void off(){...} public void high(){...} public void medium(){...} public void low(){...}}
为了简洁,就省略了类中的方法实现。。。
很明显,如果我们需要操作这些类,就需要把这些类拿到遥控器类中。我们先看下面的这种实现方法:
public class Control{ private TV tv; private CeilingLight ceilingLight; private CeilingFan ceilingFan; public Control(TV tv, CeilingLight ceilingLight, CeilingFan ceilingFan) { this.tv = tv; this.ceilingFan = ceilingFan; this.ceilingLight = ceilingLight; } public void sendCommand(int i){ if(i == EnumUtil.TV_ON){ tv.on(); }else if(i == EnumUtil.TV_OFF){ tv.off(); }else if(i == EnumUtil.FAN_ON){ ceilingFan.on(); }else if(...){ ... } ....//太多了省略 } ......}
很明显,上面的方法导致这样的问题:
1.如果增加或减少家电就需要动原来的代码。
2.如果我想调整按键的位置,就需要对原来的代码进行大规模的调整。
3.很容易写错。。。
从上面的描述可以知道,经常会变化的部分是调用厂商类的那部分。下面的命令模式就可以把“调用”的命令和遥控器解耦,使得遥控器不需要知道具体的命令。
首先定义一个命令的接口,这个接口需要继承他的类都需要实现执行命令的方法:
public interface Command{ public void excute();}
下面实现开电视机和关电视机两个动作:
public class TvOnCommand implements Command{ Tv tv; public TvOnCommand(Tv tv){ this.tv = tv; } public void excute(){ tv.on(); }}
public class TvOffCommand implements Command{ Tv tv; public TvOnCommand(Tv tv){ this.tv = tv; } public void excute(){ tv.off(); }}
这样,我们实现了第一步:将请求封装到类中。
下面是遥控器的实现类:
public class Control{ Command[] commands; public Control(int n){ //遥控器有几个按钮 if(n > 0){ commands = new Command[n]; } } public void setCommand(int slot, Command command){ commands[slot] = command; } public void pushCommand(int slot){ commands[slot].excute(); }}
这样就实现了遥控器和命令的解耦,遥控器不需要知道每个按键是什么,是怎样工作的。
下面是具体的使用方法:
public class RemoteLoader{ public static void main(String[] args) { Control control = new Control(4); TV tv = new TV(); Light light = new Light(); TvOnCommand tvOnCommand = new TvOnCommand(tv); TvOffCommand tvOffCommand = new TvOffCommand(tv); LightOnCommand lightOnCommand = new LightOnCommand(light); LightOffCommand lightOffCommand = new LightOffCommand(light); control.setCommand(0,tvOnCommand); control.setCommand(1,tvOffCommand); control.setCommand(2,lightOnCommand); control.setCommand(3,lightOffCommand); //下面就可以使用遥控器了: pushCommand(0);//打开电视机 pushCommand(1);//打开灯光 }}
上面的方式就是简单的命令模式了。最后是命令模式的类图:
- [学习笔记]设计模式[5]-{命令模式}
- 设计模式学习笔记之命令模式
- 设计模式学习笔记之命令模式
- 设计模式学习笔记-命令模式
- 设计模式学习笔记--命令模式
- [设计模式学习笔记]命令模式
- 设计模式学习笔记—命令模式
- 学习笔记:Java设计模式-命令模式
- 学习笔记:java设计模式--命令模式
- 设计模式学习笔记之命令模式
- 设计模式学习笔记--命令模式
- 【学习笔记】设计模式-命令模式
- 【设计模式学习笔记十五】【行为模式】【命令模式(Command)】
- java 设计模式学习笔记十二 command命令设计模式
- 设计模式笔记-命令模式
- 设计模式笔记--命令模式
- 设计模式笔记:命令模式
- 设计模式笔记:命令模式
- QT4.7自定义标题栏简单实现
- 全文索引
- MySQL开启记录执行过的SQL语句方法
- .NET 调用存储过程详解
- 手链样式
- [学习笔记]设计模式[5]-{命令模式}
- ios 七种手势详解
- 算法笔记_029-约瑟夫斯问题(Java)
- opencv之构建图和最大流/最小割的gcgraph.h源码解读
- 关于Struts2的拦截jsp的一些了解
- Struts2框架 的核心原理(图示浅析)
- 如何完全删除Oracle数据库
- 巧用JSON.stringify()生成漂亮格式的JSON字符串
- html简介