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

〇、小故事

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

再思考一个场景,我们作为公司的技术部的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^)/ ~ 「干货分享,每天更新」

相关推荐
2401_857439691 分钟前
SpringBoot框架在资产管理中的应用
java·spring boot·后端
怀旧6662 分钟前
spring boot 项目配置https服务
java·spring boot·后端·学习·个人开发·1024程序员节
李老头探索4 分钟前
Java面试之Java中实现多线程有几种方法
java·开发语言·面试
芒果披萨10 分钟前
Filter和Listener
java·filter
qq_49244844614 分钟前
Java实现App自动化(Appium Demo)
java
阿华的代码王国23 分钟前
【SpringMVC】——Cookie和Session机制
java·后端·spring·cookie·session·会话
德育处主任Pro1 小时前
『Django』APIView基于类的用法
后端·python·django
找了一圈尾巴1 小时前
前后端交互通用排序策略
java·交互
哎呦没3 小时前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
2401_857600953 小时前
SpringBoot框架的企业资产管理自动化
spring boot·后端·自动化