定义
Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
我们可以引入一个场景,假如一个公司在刚成立规模还小,老板还没钱给自己配秘书,老板需要和三个组(技术部、策划部、行政部)都要沟通。
代码如下:
抽象出公共方法
/**
* @author shuliangzhao
* @Title: Group
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:37
*/
public abstract class Group {
public abstract void add();
public abstract void del();
public abstract void change();
public abstract void plan();
}
策划部 PlanDepartGroup
/**
* @author shuliangzhao
* @Title: PlanDepartGroup
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:41
*/
public class PlanDepartGroup extends Group {
@Override
public void add() {
System.out.println("策划部新增策划方案");
}
@Override
public void del() {
System.out.println("策划部删除策划方案");
}
@Override
public void change() {
System.out.println("策划部修改策划方案");
}
@Override
public void plan() {
System.out.println("策划部变更策划方案");
}
}
技术部 TechDepartGroup
/**
* @author shuliangzhao
* @Title: TechDepartGroup
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:39
*/
public class TechDepartGroup extends Group {
@Override
public void add() {
System.out.println("技术部增加需求");
}
@Override
public void del() {
System.out.println("技术部删除需求");
}
@Override
public void change() {
System.out.println("技术部修改需求");
}
@Override
public void plan() {
System.out.println("技术部变更需求");
}
}
行政部 AdminDepartGroup
/**
* @author shuliangzhao
* @Title: AdminDepartGroup
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:42
*/
public class AdminDepartGroup extends Group {
@Override
public void add() {
System.out.println("行政部新增考勤规范");
}
@Override
public void del() {
System.out.println("行政部删除考勤规范");
}
@Override
public void change() {
System.out.println("行政部变更考勤规范");
}
@Override
public void plan() {
System.out.println("行政部执行新的考勤规范");
}
}
场景类
/**
* @author shuliangzhao
* @Title: Client
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:45
*/
public class Client {
public static void main(String[] args) {
System.out.println("======老板给行政组下发任务==========");
AdminDepartGroup adminDepartGroup = new AdminDepartGroup();
adminDepartGroup.add();
adminDepartGroup.change();
adminDepartGroup.del();
}
}
执行结果
image.png
然后老板又给技术部,策划部下发任务。这样每天周而复始在给不同部门下发任务,由此一来老板都没有时间规划公司的发展了,老板一看这样不行啊,必须要给自己找一个下手,来分担这样的工作。老板要的这个人,需要做的就是,我给你一个指令你去告诉大家要怎么要,不用我自己天天出面。
因此上面设计已经不符合,我们需要从新设计。
首先抽象一个Commond类,这个类只有一个execute方法。然后具体的命令继承这个Commond类。
Invoker实现类,setComand接收老板发给我们的命令,action方法是执行老板的命令。
因此我们需要增加几个类来完成我们现在的设计
命令类 Commond
/**
* @author shuliangzhao
* @Title: Commond
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 21:57
*/
public abstract class Commond {
protected AdminDepartGroup adminDepartGroup = new AdminDepartGroup();
protected PlanDepartGroup planDepartGroup = new PlanDepartGroup();
protected TechDepartGroup techDepartGroup = new TechDepartGroup();
//要告诉我做什么
public abstract void execute();
}
新增考勤规范命令
/**
* @author shuliangzhao
* @Title: AddAdminDepartGroup
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 22:00
*/
public class AddAdminDepartGroup extends Commond {
@Override
public void execute() {
super.adminDepartGroup.add();
super.adminDepartGroup.plan();
}
}
负责命令的人Invoker
/**
* @author shuliangzhao
* @Title: Invoker
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 22:01
*/
public class Invoker {
private Commond commond;
public Invoker(Commond commond) {
this.commond = commond;
}
public void action() {
commond.execute();
}
}
场景类
/**
* @author shuliangzhao
* @Title: Client
* @ProjectName design-parent
* @Description: TODO
* @date 2019/6/4 22:02
*/
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker(new AddAdminDepartGroup());
invoker.action();
}
}
执行结果
image.png
这更简单了,负责人只要接到老板的命令,就立刻执行。
命令模式的优点
1.类间解耦,调用者角色与接收者角色之间没有任何依赖关系。
2.可扩展性,Command的子类可以非常容易地扩展。
命令模式的缺点
代码写的比较多,有N个命令,就需要写N个类。