个人博客:打开链接
命令模式的定义
命令模式是一个高内聚的模式,其定义为:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或记录请求日志,可以提供命令的撤销和恢复功能.
例子:项目经理执行任务满足客户需求
过程说一下:最开始,项目经理有三个部门,美工组、需求组、代码组。客户如果有了新的需求就需要找这三个部门。
客户每个新需求都要跟他们交流,同时,还可能有顺序问题,比如客户去找美工组,但是美工组说需求组的需求不是这么写的。那这就是上一篇的中介者模式,客户不去跟这三个部门交流了,跟客户经理交流,然后客户经理自己去安排。那我们在代码里怎么交流呢?上一篇我们是用的字符串来进行交流。敲过上一篇中介者模式的同志肯定知道,字符串是很可能出问题的,错了一个字符怎么办?OK,我们把命令封装成对象不就可以了,每一个命令的执行流程我们也在对象内部定义,而不是在客户经理那里写,类间解耦合,类内部高内聚。
UML图:
public abstract class Group {
public void Output(String str){
System.out.println(str);
}
//要让这个组干活,你得首先找到这个组
public abstract void find();
//被要求增加功能
public abstract void add();
//被要求删除功能
public abstract void delete();
}
//需求组
public class RequirementGroup extends Group {
public void find() {
Output("找到需求组...");
}
//客户要加需求
public void add(){
Output("客户要求增加一项需求...");
}
public void delete(){
Output("客户要求删除一项需求...");
}
}
//代码组
public class CodeGroup extends Group {
@Override
public void find() {
Output("找到代码组...");
}
@Override
public void add() {
Output("客户要求增加一项功能...");
}
@Override
public void delete() {
Output("客户要求删除一项功能...");
}
}
//美工组
public class PageGroup extends Group{
@Override
public void find() {
Output("找到美工组...");
}
@Override
public void add() {
Output("客户要求增加一个页面...");
}
@Override
public void delete() {
Output("客户要求删除一个页面...");
}
}
public abstract class Command {
protected RequirementGroup rg = new RequirementGroup();
protected PageGroup pg = new PageGroup();
protected CodeGroup cg = new CodeGroup();
public abstract void execute();
}
//增加需求命令
public class AddRequirementCommand extends Command {
@Override
public void execute() {
super.rg.find();
super.rg.add();
}
}
//删除页面命令
public class DeletePageCommand extends Command {
@Override
public void execute() {
super.rg.find();
super.pg.delete();
}
}
//万恶的项目经理
public class Manager {
private Command command;
public void setCommand(Command command){
this.command = command;
}
public void action(){
this.command.execute();
}
}
//场景类
public class Client {
public static void main(String[] args) {
Manager xiaosan = new Manager();//定义项目经理小三先生
System.out.println("----------客户要求增加一项功能-------------");
Command command = new AddRequirementCommand();
xiaosan.setCommand(command);
xiaosan.action();
}
}
/*Output
----------客户要求增加一项功能-------------
找到需求组...
客户要求增加一项需求...
*/
可以看出,命令模式其实是把一个命令分为了三个步骤去执行,使发出命令者和接收者对象完全不关心对方是怎么操作的。
优点
1、封装性好:每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的
2、扩展性好:只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。
缺点
命令如果很多,特别是很多简单的命令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都需要写一个命令类来封装。