java设计模式-命令模式

文章参考:
汤高的Java设计模式(十八)—-命令模式
Java设计模式之命令模式


补充
刚开始对命令模式的 宏命令 撤销命令 命令队列 请求日志 不是很能理解,后面看了下面的老司机的博客,才感觉懂了一点点。
链接地址:
JsonShare猿的博客地址
命令模式基础篇 :
命令模式扩展篇 - 宏命令:
命令模式扩展篇 - 撤销命令:
命令模式扩展篇 - 命令队列:
命令模式扩展篇 - 请求日志:

顾名思义,命令模式一定是有命令发送者,命令接收者。命令发送者负责发送命令,命令接收者负责接收命令并完成具体的工作。在程序设计中,经常设计到一个对象需要请求另外一个对象调用其方法达到某种目的,如果请求着不希望或不直接和被请求者打交道,既请求者不包含被请求者的引 用,那么就可以使用命令模式。

结构

命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
  每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开 来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。

命令允许请求的一方和接收请求的一方能够独立演化,从而具有以下的优点:
1、命令模式使新的命令很容易地被加入到系统里。
2、能较容易地设计一个命令队列。
3、允许接收请求的一方决定是否要否决请求。 (暂时不理解)
4、可以容易地实现对请求的撤销和恢复。 (暂时不理解)
5、在需要的情况下,可以较容易地将命令记入日志。 (暂时不理解)

类图:
这里写图片描述

命令模式涉及到五个角色

命令(Command)角色:
声明了一个给所有具体命令类的抽象接口,规定了用来封装请求的若干个方法。
具体命令(ConcreteCommand)角色:
定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
请求者(Invoker)角色:
具体命令的管理与维护类。请求者是一个包含”命令接口“变量的类的实例。请求者中的”命令“接口的变量可以存放任何具体命令的引用,请求者负责调用具体命令,让具体命令执行那些封装了请求的方法。
接收者(Receiver)角色:
负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
客户端(Client)角色:
创建一个具体命令(ConcreteCommand)对象并确定其接收者。

以部门分配任务的案例说明:
角色:
普通员工(命令的执行者)
经理(命令的传送者)
老板(命令的发起者)


定义命令接口

package com.madman.base.designMode.command;

/**
 * 命令接口
 * 定义一个命令
 */
public interface Command{
    /**
     * 定义命令
     */
    void execute();
}

定义命令接收者

package com.madman.base.designMode.command;

/**
 * 具体命令的接受者
 * 被访问的对象
 */
public class Receiver{
    public void writeCode() {
        System.out.println("执行写代码的操作");
    }

    public void preparePPT() {
        System.out.println("准备PPT");
    }
}

命令的具体实现者

package com.madman.base.designMode.command;

/**
 * 定义具体的命令...
 * 用于管理被接受者
 */
public class CommandImpl implements Command{
    Receiver r = new Receiver();

    /**
     * 定义命令
     */
    @Override
    public void execute() {
        r.writeCode();
    }
}

命令调用者

package com.madman.base.designMode.command;

/**
 * 调用者
 * 维护命令的类
 */
public class Invoker{
    Command c;

    public Command getC() {
        return c;
    }

    /**
     * 创建人:madman
     * 创建时间:date()
     *
     * @param c
     */
    public void setC(Command c) {
        this.c = c;
    }

    public void action() {
        c.execute();
    }
}

客户端

package com.madman.base.designMode.command;

public class Client{
    public static void main(String[] args) {
        Command c = new CommandImpl();
        Invoker in = new Invoker();
        in.setC(c);
        in.action();
    }
}

执行结果

执行写代码的操作
宏命令

所谓宏命令简单点说就是包含多个命令的命令,是一个命令的组合。指挥官可以把一个一个的命令记录下来,再在任何需要的时候重新把这些记录下来的命令一次性执行,这就是所谓的宏命令集功能 

在新增一个命令的具体实现类

package com.madman.base.designMode.command;

/**
 * 定义具体的命令...
 * 用于管理被接受者
 */
public class CommandImp2 implements Command{
    Receiver r = new Receiver();

    /**
     * 定义命令
     */
    @Override
    public void execute() {
        r.preparePPT();
    }
}

新建一个Invoker2用来管理命令集合

package com.madman.base.designMode.command;

import java.util.ArrayList;
import java.util.List;

/**
 * 调用者
 * 维护命令的类
 */
public class Invoker2{
    List<Command> commandList = new ArrayList<Command>();

    public void add(Command c) {
        commandList.add(c);
    }

    public void remove(Command c) {
        commandList.remove(c);
    }

    public void action() {
        for (Command command : commandList) {
            command.execute();
        }
    }
}

客户端

package com.madman.base.designMode.command;

public class Client2{
    public static void main(String[] args) {
        Command c = new CommandImpl();
        Command c2 = new CommandImp2();
        Invoker2 in = new Invoker2();
        in.add(c);
        in.add(c2);
        in.action();
        System.out.println("-----------------");
        in.remove(c);
        in.action();
    }
}

结果

执行写代码的操作
准备PPT
-----------------
准备PPT

命令模式优点

 
更松散的耦合
  命令模式使得发起命令的对象——客户端,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。
更动态的控制
  命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。
很自然的复合命令
  命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。
更好的扩展性
  由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。

缺点

使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。

适用情况

1、系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2、系统需要在不同的时间指定请求、将请求排队和执行请求。
3、系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。(网络摘抄不理解…)
4、系统需要将一组操作组合在一起,即支持宏命令。

项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还[基于Python]自己写的一个微信跳一跳自动游戏程序(针对安卓手机)。 全自动运行 自动适应不同分辨率 自动调整各个参数误差.zip行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值