设计模式之禅——命令模式

来源:互联网 发布:tsp贪心算法 编辑:程序博客网 时间:2024/06/06 08:25

命令模式的定义

命令模式是一个高内聚的模式,其定义为:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或记录请求日志,可以提供命令的撤销和恢复功能.

例子:项目经理执行任务满足客户需求

这里我把书上的例子的演化过程说一下:最开始,项目经理有三个部门,美工组、需求组、代码组。客户如果有了新的需求就需要找这三个部门。
客户每个新需求都要跟他们交流,同时,还可能有顺序问题,比如客户去找美工组,但是美工组说需求组的需求不是这么写的。那这就是上一篇的中介者模式,客户不去跟这三个部门交流了,跟客户经理交流,然后客户经理自己去安排。那我们在代码里怎么交流呢?上一篇我们是用的字符串来进行交流。敲过上一篇中介者模式的同志肯定知道,字符串是很可能出问题的,错了一个字符怎么办?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 0
原创粉丝点击