趣解设计模式之《把意大利炮给我拿来!》

〇、小故事

回忆一下我们去饭店点餐,我们坐好,服务员给我们递过来菜单,我们点菜,点完菜我们就可以刷抖音或者玩王者荣耀了。那么过一会儿菜就上来了。谁做的菜? 怎么做的菜?厨师的名字叫啥?他是什么星座的?是不是程序员转行了? 我们一概不关心

再思考一个场景,我们作为公司的技术部的leader,有需求来了,说是现在我们商城的支付方式太少了,只有银联支付,很多用户反应需要微信支付和支付宝支付。那么你叫来了团队最靠谱的小李,然后跟他说下周希望商城有微信支付的功能,下下周有支付宝支付的功能。小李说没问题,然后你就去忙你自己的事儿了。两周后,支付宝和微信支付功能如期上线,你很开心,并且认为小李很给力。

还有就是战场上,司令员下达命令就是"把我的意大利炮拿出来,把XX山头给我打下来"。这就是命令,而具体怎么实现,部队里哪些人去做,不是司令员关心的,他只关心XX山头打下来没有

那么以上的三个例子,都是我们今天要介绍的设计模式的现实写照------命令模式

一、模式定义

命令模式Command Pattern

将"请求 "封装成命令对象,以便使用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。

为了加深模式的理解,我们假设要设计一款多功能遥控器 ,这个遥控器有一排的on开关和一排的off开关,我们可以指定某个on/off开关执行某个命令,比如开灯、关灯、打开电视等等。如下图所示:

二、模式类图

针对上面说的多功能遥控器,我们来设计对应类图,首先,需要遥控器类RemoteController ,在这个类里,包含着一排on按钮(onCommands)和一排off按钮(offCommands);其次,创建命令接口Command ,提供执行命令的方法execute();然后实现具体的指令实现类,如:LightOnCommandLightOffCommand ,当然,具体的操作灯的行为,还是在Light类中,因为这个类才是实际供应商提供给我们关于这盏灯的操作api。具体类图,请见如下所示;

三、代码实现

创建命令接口Command.java

java 复制代码
public interface Command {
    void execute();
}

创建关灯命令实现类LightOffCommand.java

java 复制代码
public class LightOffCommand implements Command {
    private Light light;
    public LightOffCommand(Light light) {
        this.light = light;
    }
    public void execute() {
        light.off();
    }
}

创建开灯命令实现类LightOnCommand.java

java 复制代码
public class LightOnCommand implements Command {
    private Light light;
    public LightOnCommand(Light light) {
        this.light = light;
    }
    public void execute() {
        light.on();
    }
}

创建无指令实现类NoCommand.java

java 复制代码
public class NoCommand implements Command {
    public void execute() {
        System.out.println("Doing nothing!");
    }
}

创建供应商所属灯的API类Light.java

java 复制代码
public class Light {
    /** 开灯操作 */
    public void on() {
        System.out.println("Light on!");
    }
    /** 关灯操作 */
    public void off() {
        System.out.println("Light off!");
    }
}

创建遥控器类RemoteController.java

java 复制代码
public class RemoteController {
    private Command[] onCommands;
    private Command[] offCommands;

    public RemoteController() {
        onCommands = new Command[4];
        offCommands = new Command[4];

        for (int i = 0; i < 4; i++) {
            onCommands[i] = new NoCommand();
            offCommands[i] = new NoCommand();
        }
    }

    /** 往遥控器中添加命令 */
    public void addCommand(int slot, Command onCommand, 
                           Command offCommand) {
        onCommands[slot] = onCommand;
        offCommands[slot] = offCommand;
    }

    /** 按遥控器中某个开启键 */
    public void pushOnButton(int slot) {
        onCommands[slot].execute();
    }

    /** 按遥控器中某个关闭键 */
    public void pushOffButton(int slot) {
        offCommands[slot].execute();
    }
}

创建测试类CommandTest.java

java 复制代码
public class CommandTest {
    public static void main(String[] args) {
        Light light = new Light();
        RemoteController controller = new RemoteController();
        controller.addCommand(0, new LightOnCommand(light), 
                              new LightOffCommand(light));
        controller.pushOnButton(0); // 按下遥控器,第一排的ON按钮
        controller.pushOffButton(0); // 按下遥控器,第一排的OFF按钮
    }
}

输出结果

vbnet 复制代码
Light on!
Light off!

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ21 分钟前
如何使用Java WebSocket API实现客户端和服务器端的通信?
java·开发语言·websocket
是小崔啊34 分钟前
tomcat源码02 - 理解Tomcat架构设计
java·tomcat
没有bug.的程序员1 小时前
JAVA面试宝典 -《安全攻防:从 SQL 注入到 JWT 鉴权》
java·安全·面试
栈溢出了1 小时前
MyBatis实现分页查询-苍穹外卖笔记
java·笔记·mybatis
31535669131 小时前
Springboot实现一个接口加密
后端
morningcat20181 小时前
java17 gc笔记
java·jvm·笔记
1 小时前
Unity开发中常用的洗牌算法
java·算法·unity·游戏引擎·游戏开发
Your易元2 小时前
设计模式-模板方法模式
java·设计模式·模板方法模式
risc1234562 小时前
Elasticsearch 线程池
java·大数据·elasticsearch
Linn3 小时前
Spring WebSocket 服务实现的主流方案与最佳实践
spring boot·后端·spring