Android 架构师5 设计模式之命令模式
前言
命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,there by letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请 求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
需求
一个项目中有需求组、美工组、代码组,刚开始的时候客户还是很乐意和我们每个组探讨,比如和需求组讨论需求,和美工讨论页面,和代码组讨论实现,告诉他们修改这里,删除这里,增加这些等等。
![](https://img.haomeiwen.com/i6069538/71289a90e5c638c7.png)
基本实现与问题
组的抽象类Group,毕竟面向接口编程嘛:
public abstract class Group {
//首先找到对应的组
public abstract void find();
//被要求添加一个功能
public abstract void add();
//被要求删除一个功能
public abstract void delete();
//被要求改变一个功能
public abstract void change();
//被要求给出所有的变更计划
public abstract void plan();
}
需求组RequirementGroup:
public class RequirementGroup extends Group {
@Override
public void find() {
System.out.println("找到需求组...");
}
@Override
public void add() {
System.out.println("客户要求增加一个需求...");
}
@Override
public void delete() {
System.out.println("客户要求删除一个需求...");
}
@Override
public void change() {
System.out.println("客户要求改变一个需求...");
}
@Override
public void plan() {
System.out.println("客户要求需求变更计划...");
}
}
美工组PageGroup:
public class PageGroup extends Group {
@Override
public void find() {
System.out.println("找到美工组...");
}
@Override
public void add() {
System.out.println("客户要求增加一个页面...");
}
@Override
public void delete() {
System.out.println("客户要求删除一个页面...");
}
@Override
public void change() {
System.out.println("客户要求改变一个页面...");
}
@Override
public void plan() {
System.out.println("客户要求界面修改计划...");
}
}
代码组CodeGroup:
public class CodeGroup extends Group {
@Override
public void find() {
System.out.println("找到代码组...");
}
@Override
public void add() {
System.out.println("客户要求增加一个功能...");
}
@Override
public void delete() {
System.out.println("客户要求删除一个功能...");
}
@Override
public void change() {
System.out.println("客户要求改变一个功能...");
}
@Override
public void plan() {
System.out.println("客户要求修改功能计划...");
}
}
整个项目的三个支柱已经产生了,接下来就要看看客户Client端怎么跟我们沟通了:
public class Client {
public static void main(String[] args) {
Group group = new RequirementGroup();
group.find();
group.add();
group.plan();
}
}
这是客户增加一个需求,由需求组去处理,代码输出结果为:
找到需求组...
客户要求增加一个需求...
客户要求需求变更计划...
这时候,客户需要美工组增加一个页面,代码实现是这样的:
public class Client {
public static void main(String[] args) {
Group group = new PageGroup();
group.find();
group.add();
group.plan();
}
}
显然对于这样的修改是可以接受的,但是如果现实生活中,每有一个需求都需要客户单独找需求组或者美工组或者代码组去,恐怕客户和每个组都是不乐意这么去做的吧!这时候客户就跟产品经理说,你们别这样麻烦了,给我一个接头人,我发出需求的命令给你这个接头人,然后你们内部怎么处理,就由这个接头人去安排吧!接下来我们看命令模式是怎么实现的。
命令模式
提供一个命令的抽象类Command:
public abstract class Command {
protected RequirementGroup rg = new RequirementGroup();
protected PageGroup pg = new PageGroup();
protected CodeGroup cg = new CodeGroup();
//执行事情的方法
public abstract void execute();
}
增加一个需求的命令类AddRequirementCommand:
public class AddRequirementCommand extends Command {
@Override
public void execute() {
rg.find();
rg.add();
rg.plan();
}
}
删除一个页面的命令类DeletePageCommand:
public class DeletePageCommand extends Command {
@Override
public void execute() {
pg.find();
pg.delete();
pg.plan();
}
}
接头人Invoker:
public class Invoker {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void execute() {
if (command != null) {
command.execute();
}
}
}
这时候客户端的请求是这样的:
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker();
AddRequirementCommand command = new AddRequirementCommand();
invoker.setCommand(command);
invoker.execute();
}
}
运行结果为:
找到需求组...
客户要求增加一个需求...
客户要求需求变更计划...
如果是删除一个页面的命令,我们只需要new DeletePageCommand()即可,是不是很简单呢?而且满足对修改关闭,对扩展开放的设计原则。更令人满意的是,如果有一个需求,需要三个小组配合完成,也是非常简单的,只需要重新设计一个Command的实现类即可。
总结
命令模式比较简单,但是在项目中使用是非常频繁的,封装性比较好,将请求者和执行者分开了,扩展性也有很好的保障;但是由于需求不断地增加,可能会导致Command的实现类过多。
喜欢本篇博客的简友们,就请来一波点赞,您的每一次关注,将成为我前进的动力,谢谢!作者:zhang_pan