【Java设计模式】 Java设计模式之(六)命令模式(Command Pattern)


命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

一、命令模式介绍

意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

如何解决:通过调用者调用接受者执行命令,顺序:调用者→命令→接受者。

关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口

应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。

优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。

注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。

二、代码实现

所有设计模式的代码实现例子都可在码云上查看哦,感兴趣的可以查看哈,码云地址:https://gitee.com/no8g/java-design-patterns

2.1 通用类图

在这个类图中,我们看到三个角色:

Receiver 角色:这个就是干活的角色,命令传递到这里是应该被执行的,具体到上面我们的例子中就是Group 的三个实现类;

Command 角色:就是命令,需要我执行的所有命令都这里声明;

Invoker 角色:调用者,接收到命令,并执行命令,例子中我这里项目经理就是这个角色;

命令模式比较简单,但是在项目中使用是非常频繁的,封装性非常好,因为它把请求方(Invoker)和执行方(Receiver)分开了,扩展性也有很好的保障。但是,命令模式也是有缺点的,你看 Command 的子类没有,那个如果我要写下去的可不是几个,而是几十个,这个类膨胀的非常多,这个就需要大家在项目中自己考虑使用了。

2.2 代码实现

package com.iot.practice.designpattern.command.commandpattern;/** * <p>CommandClient 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:45</p> * <p>@remark:</p> */public class CommandClient {    public static void main(String[] args) {        // 定义我们的接头人        Invoker zhangSan = new Invoker();        // 客户要求增加一项需求        System.out.println("\n-------------客户要求增加一项需求-----------------");        // 客户给我们下命令来        Command command = new AddRequirementCommand();        // 接头人接收到命令        zhangSan.setCommand(command);        // 接头人执行命令        zhangSan.action();        // 客户要求增加一项需求        System.out.println("\n-------------客户要求删除一个页面-----------------");        // 客户给我们下命令来        Command command1 = new DeletePageCommand();        //接头人接收到命令        zhangSan.setCommand(command1);        //接头人执行命令        zhangSan.action();    }}
package com.iot.practice.designpattern.command.commandpattern;import com.iot.practice.designpattern.command.CodeGroup;import com.iot.practice.designpattern.command.PageGroup;import com.iot.practice.designpattern.command.RequirementGroup;/** * <p>Command 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:34</p> * <p>@remark:命令的抽象类,我们把客户发出的命令定义成一个一个的对象</p> */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.iot.practice.designpattern.command.commandpattern;/** * <p>Invoker 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:42</p> * <p>@remark:接头人的职责就是接收命令,并执行</p> */public class Invoker {    /**     * 什么命令     */    private Command command;    /**     * 客户发出命令     */    public void setCommand(Command command) {        this.command = command;    }    /**     * 执行客户的命令     */    public void action() {        this.command.execute();    }}
package com.iot.practice.designpattern.command.commandpattern;/** * <p>AddRequirementCommand 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:38</p> * <p>@remark:增加一项需求</p> */public class AddRequirementCommand extends Command {    /**     * 执行增加一项需求的命令     */    @Override    public void execute() {        // 找到需求组        super.requirementGroup.find();        // 增加一份需求        super.requirementGroup.add();        // 给出计划        super.requirementGroup.plan();    }}
package com.iot.practice.designpattern.command.commandpattern;/** * <p>DeleltePageCommand 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:41</p> * <p>@remark:<删除一个页面的命令/p> */public class DeletePageCommand extends Command {    /**     * 执行删除一个页面的命令     */    @Override    public void execute() {        // 找到页面组        super.pageGroup.find();        // 删除一个页面        super.pageGroup.delete();        // 给出计划        super.pageGroup.plan();    }}
package com.iot.practice.designpattern.command;/** * <p>Group 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:11</p> * <p>@remark:项目组分成了三个组,每个组还是要接受增删改的命令</p> */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.iot.practice.designpattern.command;/** * <p>RequirementGroup 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:14</p> * <p>@remark:</p> */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("客户要求需求变更计划...");    }}
package com.iot.practice.designpattern.command;/** * <p>PageGroup 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:23</p> * <p>@remark:美工组的职责是设计出一套漂亮、简单、便捷的界面</p> */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("客户要求页面变更计划...");    }}
package com.iot.practice.designpattern.command;/** * <p>CodeGroup 此类用于:</p> * <p>@author:hujm</p> * <p>@date:2021年02月19日 15:27</p> * <p>@remark:代码组的职责是实现业务逻辑,当然包括数据库设计了</p> */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("客户要求代码变更计划...");    }}

完结!

(0)

相关推荐

  • 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

    设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

  • CommandPattern命令模式

    命令模式 1.定义 将一个请求封装成一个对象,从而可以使用不同的请求来参数化客户端. 命令模式通常有3种角色 Receiver:接收者角色.负责执行命令的角色 抽象接收者:具有所有特性的接收者的集合 ...

  • 图解Java设计模式之命令模式

    智能生活项目需求 命令模式基本介绍 命令模式的原理类图 命令模式在Spring框架中JdbcTemplate应用源码分析 命令模式的注意事项和细节 智能生活项目需求 看一个具体的需求 我们买类一套智能 ...

  • 简说设计模式——命令模式

    一.什么是命令模式 在说命令模式前我们先来说一个小例子.很多人都有吃夜市的经历,对于那些推小车的摊位,通常只有老板一个人,既负责制作也负责收钱,我要两串烤串多放辣,旁边的人要了三串烤面筋不要辣,过了一 ...

  • java设计模式-命令模式(Command)

    定义命令模式属于对象的行为模式.命令模式又称为行动(Action)模式或者交易(Transaction)模式.命令模式把一个请求或者操作封装到一个对象中.命令模式允许系统使用不同的请求把客户端参数化, ...

  • Java设计模式【命令模式】

    命令模式 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不 ...

  • 详解JAVA面向对象的设计模式 (四)、外观模式

    外观模式 Facade 外观模式内容相对简单,就不写新的例子了.本篇文章摘录自 http://c.biancheng.net/view/1369.html 外观模式的定义与特点 外观(Facade)模 ...

  • 详解JAVA面向对象的设计模式 (二)、策略模式

    策略模式 Strategy 介绍 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和 ...

  • PHP设计模式之命令模式

    PHP设计模式之命令模式 命令模式,也称为动作或者事务模式,很多教材会用饭馆来举例.作为顾客的我们是命令的下达者,服务员是这个命令的接收者,菜单是这个实际的命令,而厨师是这个命令的执行者.那么,这个模 ...

  • [PHP小课堂]PHP设计模式之命令模式

    [PHP小课堂]PHP设计模式之命令模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • Java动态代理设计模式

    本文主要介绍Java中两种常见的动态代理方式:JDK原生动态代理和CGLIB动态代理. 什么是代理模式 就是为其他对象提供一种代理以控制对这个对象的访问.代理可以在不改动目标对象的基础上,增加其他额外 ...