一、命令模式的定义
命令模式是一个高内聚的模式
将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
二、命令模式的优点
1、类间解耦
调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
2、可扩展性
Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严重的代码耦合。
3、命令模式结合其他模式会更优秀
命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少Command子类的膨胀问题
三、命令模式的缺点
命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项
目中慎重考虑使用。
四、命令模式的使用场景
只要你认为是命令的地方就可以采用命令模式,例如,在GUI开发中,一个按钮的点击
是一个命令,可以采用命令模式;模拟DOS命令的时候,当然也要采用命令模式;触发-反馈机制的处理等。
代码 :
客户的一些需求
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
public abstract class Group {
//甲乙双方分开办公,如果你要和某个组讨论,你首先要找到这个组
public abstract void find();
//被要求增加功能
public abstract void add();
//被要求删除功能
public abstract void delete();
//被要求修改功能
public abstract void change();
//被要求给出所有的变更计划
public abstract void plan();
}
研发部
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
public class CodeGroup extends Group {
//客户要求代码组过去和他们谈
public void find() {
System.out.println("找到代码组...");
}
//客户要求增加一项功能
public void add() {
System.out.println("客户要求增加一项功能...");
}
//客户要求修改一项功能
public void change() {
System.out.println("客户要求修改一项功能...");
}
//客户要求删除一项功能
public void delete() {
System.out.println("客户要求删除一项功能...");
}
//客户要求给出变更计划
public void plan() {
System.out.println("客户要求代码变更计划...");
}
}
设计部
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
public class PageGroup extends Group {
//首先这个美工组应该能找到吧,要不你跟谁谈?
public void find() {
System.out.println("找到美工组...");
}
//美工被要求增加一个页面
public void add() {
System.out.println("客户要求增加一个页面...");
}
//客户要求对现有界面做修改
public void change() {
System.out.println("客户要求修改一个页面...");
}
//甲方是老大,要求删除一些页面
public void delete() {
System.out.println("客户要求删除一个页面...");
}
//所有的增、删、改都要给出计划
public void plan() {
System.out.println("客户要求页面变更计划...");
}
}
需求部
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
public class RequirementGroup extends Group {
//客户要求需求组过去和他们谈
public void find() {
System.out.println("找到需求组...");
}
//客户要求增加一项需求
public void add() {
System.out.println("客户要求增加一项需求...");
}
//客户要求修改一项需求
public void change() {
System.out.println("客户要求修改一项需求...");
}
//客户要求删除一项需求
public void delete() {
System.out.println("客户要求删除一项需求...");
}
//客户要求给出变更计划
public void plan() {
System.out.println("客户要求需求变更计划...");
}
}
运行
public class Client {
public static void main(String[] args) {
//首先客户找到需求组说,过来谈需求,并修改System.out.println("-----------客户要求增加一项需求---------------");
Group rg = new RequirementGroup();
//找到需求组
rg.find();
//增加一个需求
rg.add();
//要求变更计划
rg.plan();
}
}
运行的结果如下所示:
-------------客户要求增加一项需求-----------------
找到需求组...
客户要求增加一项需求...
客户要求需求变更计划...
大家有没有发现每次客户提出要求的时候都是找一个组的人 , 但是我们现实中是这样子吗 ? 肯定不是的 , 如果客户有需求肯定会联系你的老大然后你老大让你去修改或添加新的需求 , 好那我们也来用代码实现它 , 比如让设计部 和 需求部去修改一些需求
我们有几个相关的部门
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
/**
* Created by liangshaoteng on 17-7-26.
*/
public abstract class Command {
protected RequirementGroup requirementGroup = new RequirementGroup();
protected PageGroup pageGroup = new PageGroup();
protected CodeGroup codeGroup = new CodeGroup();
public abstract void execute();
}
首先我们需要来创建一个领导,来管理
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
/**
* Created by liangshaoteng on 17-7-26.
*/
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void action(){
this.command.execute();
}
}
这个时候客户突然有了新的需求,找到了你的领导然后需要你修改一些东西
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
/**
* Created by liangshaoteng on 17-7-26.
*/
public class DeletePageCommand extends Command {
@Override
public void execute() {
super.pageGroup.find();
super.pageGroup.delete();
super.pageGroup.plan();
}
}
package com.example.liangshaoteng.myapplication.shejimoshizicandao.danyizhizhe.minglinghang;
/**
* Created by liangshaoteng on 17-7-26.
*/
public class AddRequirementCommand extends Command {
@Override
public void execute() {
super.requirementGroup.find();
super.requirementGroup.add();
super.requirementGroup.plan();
}
}
运行场景 :
public class Client {
public static void main(String[] args) {
//首先声明调用者Invoker
Invoker invoker = new Invoker();
//定义接收者
Receiver receiver = new ConcreteReciver1();
//定义一个发送给接收者的命令
Command command = new ConcreteCommand1(receiver);
//把命令交给调用者去执行
invoker.setCommand(command);
invoker.action();
}
}
OK ! 我们的命令模式就算完成啦 !