设计模式学习笔记:命令模式(Command)

在一切变好之前,我们总要经历一些不开心的日子,这段日子也许很长,也许只是一觉醒来。有时候,选择快乐,更需要勇气。

一、命令模式简介

命令模式是设计模式中行为型模式的一种。它是一种数据驱动的模式,将命令封装成一个对象传递给调用者,调用者根据请求的不同寻找合适的命令对象,命令对象调用相应的接收者完成请求。

在这里插入图片描述

涉及到的角色

Client: 客户端,下达命令。

Invoker: 持有大量的命令,命令的调度者。

Command: 命令的抽象接口,声明命令需要实现的方法。

ConcreteCommand: 命令接口的实现,调用相应的接收者执行命令。

Receiver: 接收者,命令的实际执行者,可以是任何对象,只要能完成命令的要求就可以。

二、实现方式

下面通过代码实现来理解命令模式的作用。

场景如下:

客户端操作灯的开关、音响的开关及音量的调节等功能。通过命令模式设计出易扩展的系统。

系统中共有如下一些类:

  • Client:客户端
  • Command:命令接口
  • RemoteInvoker:调用者
  • LightOffCommand:关灯的命令
  • LightOnCommand:开灯的命令
  • LightReceiver:灯的开关(接收者)
  • SoundOffCommand:关闭音响的命令
  • SoundOnCommand:打开音响的命令
  • SoundTurnDownCommand:调低音量的命令
  • SoundTurnUpCommand:调高音量的命令
  • SoundReceiver:音响的操作

代码实现

Client:客户端

/**
 * 客户端
 *
 * @author ZhengNC
 * @date 2020/7/21 17:52
 */
public class Client {

    public static void main(String[] args) {
        //创建调用者
        RemoteInvoker remoteInvoker = new RemoteInvoker();

        //创建接收者
        LightReceiver lightReceiver = new LightReceiver();
        SoundReceiver soundReceiver = new SoundReceiver();

        //向调用者中添加可执行的命令
        remoteInvoker.addCommand("lightOn", new LightOnCommand(lightReceiver));
        remoteInvoker.addCommand("lightOff", new LightOffCommand(lightReceiver));
        remoteInvoker.addCommand("soundOn", new SoundOnCommand(soundReceiver));
        remoteInvoker.addCommand("soundOff", new SoundOffCommand(soundReceiver));
        remoteInvoker.addCommand("soundTurnUp", new SoundTurnUpCommand(soundReceiver));
        remoteInvoker.addCommand("soundTurnDown", new SoundTurnDownCommand(soundReceiver));

        //发送开灯命令
        remoteInvoker.execute("lightOn");
        //撤销开灯命令
        remoteInvoker.undo("lightOn");

        //发送关灯命令
        remoteInvoker.execute("lightOff");
        //撤销关灯命令
        remoteInvoker.undo("lightOff");

        //音响的操作
        remoteInvoker.execute("soundOn");
        remoteInvoker.execute("soundOff");
        remoteInvoker.execute("soundOn");
        remoteInvoker.execute("soundTurnUp");
        remoteInvoker.execute("soundTurnDown");
    }
}

Command:命令接口

/**
 * 命令接口
 *
 * @author ZhengNC
 * @date 2020/7/21 17:01
 */
public interface Command {

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

    /**
     * 撤销命令
     */
    void undo();
}

RemoteInvoker:调用者

/**
 * 调用者
 *
 * @author ZhengNC
 * @date 2020/7/21 17:42
 */
public class RemoteInvoker {

    private Map<String, Command> commandMap = new HashMap<>();

    /**
     * 添加一条命令
     *
     * @param name
     * @param command
     */
    public void addCommand(String name, Command command){
        if (commandMap.containsKey(name)){
            System.out.println("此命令名已存在!");
            return;
        }
        if (commandMap.containsValue(command)){
            System.out.println("此命令已存在!");
            return;
        }
        commandMap.put(name, command);
    }

    /**
     * 移除一条命令
     *
     * @param name
     */
    public void removeCommand(String name){
        commandMap.remove(name);
    }

    /**
     * 执行命令
     *
     * @param name
     */
    public void execute(String name){
        Command command = commandMap.get(name);
        if (command != null){
            command.execute();
        }else {
            System.out.println("命令不存在!");
        }
    }

    /**
     * 撤销命令
     *
     * @param name
     */
    public void undo(String name){
        Command command = commandMap.get(name);
        if (command != null){
            command.undo();
        }else {
            System.out.println("命令不存在!");
        }
    }
}

LightOffCommand:关灯的命令

/**
 * 关灯的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 17:20
 */
public class LightOffCommand implements Command {

    private LightReceiver lightReceiver;

    public LightOffCommand(LightReceiver lightReceiver){
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.off();
    }

    @Override
    public void undo() {
        lightReceiver.on();
    }
}

LightOnCommand:开灯的命令

/**
 * 开灯的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 17:17
 */
public class LightOnCommand implements Command {

    private LightReceiver lightReceiver;

    public LightOnCommand(LightReceiver lightReceiver){
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.on();
    }

    @Override
    public void undo() {
        lightReceiver.off();
    }
}

LightReceiver:灯的开关(接收者)

/**
 * 灯的开关(接收者)
 *
 * @author ZhengNC
 * @date 2020/7/21 17:07
 */
public class LightReceiver {

    /**
     * 开灯
     */
    public void on(){
        System.out.println("灯亮了。。。");
    }

    public void off(){
        System.out.println("灯暗了。。。");
    }

}

SoundOffCommand:关闭音响的命令

/**
 * 关闭音响的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 18:21
 */
public class SoundOffCommand implements Command {

    private SoundReceiver soundReceiver;

    public SoundOffCommand(SoundReceiver soundReceiver){
        this.soundReceiver = soundReceiver;
    }

    @Override
    public void execute() {
        soundReceiver.off();
    }

    @Override
    public void undo() {
        soundReceiver.on();
    }
}

SoundOnCommand:打开音响的命令

/**
 * 打开音响的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 18:21
 */
public class SoundOnCommand implements Command {

    private SoundReceiver soundReceiver;

    public SoundOnCommand(SoundReceiver soundReceiver){
        this.soundReceiver = soundReceiver;
    }

    @Override
    public void execute() {
        soundReceiver.on();
    }

    @Override
    public void undo() {
        soundReceiver.off();
    }
}

SoundTurnDownCommand:调低音量的命令

/**
 * 调低音量的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 18:21
 */
public class SoundTurnDownCommand implements Command {

    private SoundReceiver soundReceiver;

    public SoundTurnDownCommand(SoundReceiver soundReceiver){
        this.soundReceiver = soundReceiver;
    }

    @Override
    public void execute() {
        soundReceiver.turnDownVolume();
    }

    @Override
    public void undo() {
        soundReceiver.turnUpVolume();
    }
}

SoundTurnUpCommand:调高音量的命令

/**
 * 调高音量的命令
 *
 * @author ZhengNC
 * @date 2020/7/21 18:21
 */
public class SoundTurnUpCommand implements Command {

    private SoundReceiver soundReceiver;

    public SoundTurnUpCommand(SoundReceiver soundReceiver){
        this.soundReceiver = soundReceiver;
    }

    @Override
    public void execute() {
        soundReceiver.turnUpVolume();
    }

    @Override
    public void undo() {
        soundReceiver.turnDownVolume();
    }
}

SoundReceiver:音响的操作

/**
 * 音响的操作
 *
 * @author ZhengNC
 * @date 2020/7/21 18:08
 */
public class SoundReceiver {

    private boolean onOff = false;

    private int volume = 5;

    private final int maxVolume = 10;

    private final int minVolume = 0;

    /**
     * 打开音响
     */
    public void on(){
        onOff = true;
        System.out.println("音响打开了。。。");
    }

    /**
     * 关闭音响
     */
    public void off(){
        onOff = false;
        System.out.println("音响关闭了。。。");
    }

    /**
     * 调高音量
     */
    public void turnUpVolume(){
        if (onOff){
            if (volume < maxVolume){
                volume++;
                System.out.println("调高音量,当前音量:"+volume);
            }else {
                System.out.println("音量已经最大了");
            }
        }else {
            System.out.println("音响处于关闭状态");
        }
    }

    /**
     * 降低音量
     */
    public void turnDownVolume(){
        if (onOff){
            if (volume > minVolume){
                volume--;
                System.out.println("调低音量,当前音量:"+volume);
            }else {
                System.out.println("音量已经最小了");
            }
        }else {
            System.out.println("音响处于关闭状态");
        }
    }
}

运行结果展示

灯亮了。。。
灯暗了。。。
灯暗了。。。
灯亮了。。。
音响打开了。。。
音响关闭了。。。
音响打开了。。。
调高音量,当前音量:6
调低音量,当前音量:5
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值