Java行为型设计模式 —— 命令模式打响战争的开始

一、引言

阳光明媚的一个周末。

上一章讲了模板方法设计模式,今天小编继续来说命令设计模式,也是行为型设计模式的一种~~~~

二、命令模式基本介绍

所谓命令模式,就是下达命令,最后有人执行命令。

大家想想古代打战的时候,将军下达命说,明天需要攻下某某某山头。

那么将军就找来了参谋长,这个时候参谋长得知了将军的意思,参谋长就找来每个军营的负责人,说一营、二营全部人员明天出发某某某山头。

你看将军其实他并不知道是哪个具体营的士兵大战,中间通过了这个参谋长来给军营的人沟通。

命令模式(Command Pattern)思想也是如此,我们经常需要向某些对象发送请求,但是不知道到请求的接收者是谁。在命令模式中,会将一个请求或者说一个命令封装成为一个对象,我们只需要在程序运行时指定具体的请求接收者即可。更加通俗的来说,将军发布命令,参谋长得知命令通知士兵,士兵具体执行该命令,由此可见,命令模式使得请求的发送者(将军)与请求的接收者(士兵)消除彼此之间的耦合度,让对象之间的调用更加灵活,实现解耦。

三、命令模式案例演示

呐呐呐呐呐呐么,就以刚刚举例打战的案例来使用具体代码实现。

打战就肯定要有士兵,所以我们先来创建一个士兵的类,并且定义士兵所能做的事。士兵也是最后命令的执行者

/**
 * @Auther: IT贱男
 * @Date: 2019/12/13 10:40
 * @Description: 定义士兵动作,命令执行者
 */
public class Robot {

    private String name;

    public Robot(String name) {
        this.name = name;
    }

    /**
     * 士兵开火
     */
    public void fire() {
        System.out.println(this.name + "正在开火......");
    }

    /**
     * 士兵停火
     */
    public void stop() {
        System.out.println(this.name + "停止开火......");
    }
}

定义抽象的命令,可以定义命令的行为,比如执行命令,撤销命令。 有抽象的命令,那么当然就肯定有具体执行命令对象。文章上面有说,会将一个请求或者说一个命令封装成为一个对象,那么既一个命令就是一个对象。接下来我们还要创建开火和停止开火的两个命令对象。

/**
 * @Auther: IT贱男
 * @Date: 2019/12/12 13:58
 * @Description: 抽象命令者
 */
public interface Command {

    /**
     * 执行命令
     */
    void execute();

}
/**
 * @Auther: IT贱男
 * @Date: 2019/12/13 10:44
 * @Description: 开火命令,将命令请求封装成对象
 */
public class RobotFireCommand implements Command {

    // 聚合士兵,士兵是具体执行者
    private Robot robot;

    public RobotFireCommand(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void execute() {
        // 调用士兵的开火方法
        robot.fire();
    }
}
/**
 * @Auther: IT贱男
 * @Date: 2019/12/13 10:47
 * @Description: 停止开火命令,将命令请求封装成对象
 */
public class RobotStopCommand implements Command {

    private Robot robot;

    public RobotStopCommand(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void execute() {
        robot.stop();
    }
}

士兵和命令都有了,那么这个时候常参谋长就该登场了,参谋长就可以接收命令,以及通知执行命令。

/**
 * @Auther: IT贱男
 * @Date: 2019/12/13 10:48
 * @Description: 参谋长的角色 负责接受命令,以及通知士兵执行
 */
public class Staff {

    // 命令集合
    private List<Command> commandList = new ArrayList<>();

    // 添加命令
    public void addCommand(Command command) {
        commandList.add(command);
    }

    // 执行命令
    public void excuteCommands() {
        for (Command command : commandList) {
            command.execute();
        }
        commandList.clear();
    }

}
/**
 * @Auther: IT贱男
 * @Date: 2019/12/13 10:59
 * @Description:
 */
public class Client {

    public static void main(String[] args) {
        // 创建一个士兵
        Robot robot = new Robot("张三");
        RobotFireCommand fireCommand = new RobotFireCommand(robot);

        // 这个时候参谋长得知了将军的消息,要开火了
        Staff staff = new Staff();
        staff.addCommand(fireCommand);
        // 下达命令给士兵
        staff.excuteCommands();

        // 这个时候敌人消灭了,下命令停止开火
        RobotStopCommand stopCommand = new RobotStopCommand(robot);
        staff.addCommand(stopCommand);
        // 下达命令给士兵
        staff.excuteCommands();


    }

}

四、命令模式使用注意细节

命令模式最主要的作用就是把请求的调用者和请求执行者进行解耦,每一个具体命令就是单独的一个对象,缺点也就很显而易见了,如果有很多命令就会导致类爆炸的问题。

其实一个严谨的命令模式,往往还需要支持撤销的功能,本章小编就没有演示了,因为单单在命令模式中使用撤销,小编感觉稍微有点点的鸡肋。 命令模式可以和备忘录模式进行组合使用,这样备忘录可以记录上一次的操作,命令模式就可以撤销上一次的操作了。

总的来说,命令模式还是比较好理解的。

发布了152 篇原创文章 · 获赞 422 · 访问量 43万+

猜你喜欢

转载自blog.csdn.net/weixin_38111957/article/details/103521867