设计模式之命令模式

写在前面

本文看下命令设计模式。

1:介绍

1.1:什么时候使用命令设计模式

如果某个对象依赖于外部传入的具体参数来执行具体的操作时,就可以考虑使用命令设计模式,如空调的制冷,制热,小爱同学的唱歌,讲笑话等,都是通过外部的具体指令发生的操作。

1.2:UML类图

原型设计模式,包含如下元素:

1:Receiver
    负责执行具体指令的类,即能够执行特定操作的类
2:Command
    命令抽象,内部维护Receiver,通过Recevier让命令最终变成具体的动作
3:Invoker
    维护一组Command,并执行这组指令
4:客户端
    负责创建Invoker,并设置相关需要执行的指令

2:实例

源码 。

2.1:场景

小明家里有一台空调,可以控制其制冷和制热,有一个小爱同学,可以控制其唱歌和讲笑话。

2.2:程序

  • 定义空调Receiver
// 空调
public class AirConditionerReceiver {
    // 制冷
    public void cold() {
        System.out.println("空调制冷了");
    }

    // 制热
    public void hot() {
        System.out.println("空调制热了");
    }
}
  • 定义小爱同学Receiver
// 小爱同学
public class XiaoAiTongXueReceiver {
    // 唱歌
    public void sing() {
        System.out.println("小爱同学唱歌了");
    }

    // 讲笑话
    public void joke() {
        System.out.println("小爱同学讲笑话了");
    }
}

接着我们来定义用来执行空调制冷,空调制热,小爱同学唱歌,小爱同学讲笑话的Command类,首先定义接口:

// 命令的抽象,
public interface Command {
    void exec();
}
  • 各种执行具体动作的Command
    一共四个,分别是执行空调制冷的Command,空调制热的Command,小爱同学唱歌的Command,小爱同学讲笑话的Command,如下:
// 制冷命令,内部调用空调的制冷操作
public class ColdCommand implements Command {
    private AirConditionerReceiver receiver;

    public ColdCommand(AirConditionerReceiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void exec() {
        this.receiver.cold();
    }
}

// 制热命令,内部调用空调的制热操作
public class HotCommand implements Command {
    private AirConditionerReceiver receiver;

    public HotCommand(AirConditionerReceiver receiver) {
        this.receiver = receiver;
    }
    @Override
    public void exec() {
        this.receiver.hot();
    }
}

// 唱歌命令,内部调用小爱同学的唱歌
public class SingCommand implements Command {
    private XiaoAiTongXueReceiver xiaoAiTongXue;

    public SingCommand(XiaoAiTongXueReceiver xiaoAiTongXue) {
        this.xiaoAiTongXue = xiaoAiTongXue;
    }

    @Override
    public void exec() {
        this.xiaoAiTongXue.sing();
    }
}

// 讲笑话命令,内部调用小爱同学的讲笑话
public class JokeCommand implements Command {
    private XiaoAiTongXueReceiver xiaoAiTongXue;

    public JokeCommand(XiaoAiTongXueReceiver xiaoAiTongXue) {
        this.xiaoAiTongXue = xiaoAiTongXue;
    }
    
    @Override
    public void exec() {
        this.xiaoAiTongXue.joke();
    }
}
  • 定义Invoker
    维护一组要执行的Command,其中Command的设置由客户端完成:
public class MyInvoker {
    // 自己用(仅本类用)private
    // 不可改变引用值 final
    private final List<Command> commands = new ArrayList<Command>();

    // 设置一组命令,由命令来完成具体的动作,内部操作是如何完成的对用户是透明的
    public void addCommand(Command command) {
        this.commands.add(command);
    }

    // 执行命令
    public void execCommand() {
        commands.forEach(v -> v.exec());
    }
}
  • 客户端
public static void main(String[] args) {
    // 创建具体命令的执行者们
    AirConditionerReceiver airConditionerReceiver
            = new AirConditionerReceiver();
    XiaoAiTongXueReceiver xiaoAiTongXueReceiver = new XiaoAiTongXueReceiver();

    // 创建命令
    Command singCommand = new SingCommand(xiaoAiTongXueReceiver);
    Command jokeCommand = new JokeCommand(xiaoAiTongXueReceiver);
    Command coldCommand = new ColdCommand(airConditionerReceiver);
    Command hotCommand = new HotCommand(airConditionerReceiver);

    // 把命令添加到invoker
    MyInvoker myInvoker = new MyInvoker();
    myInvoker.addCommand(singCommand);
    myInvoker.addCommand(jokeCommand);
    myInvoker.addCommand(hotCommand);
    myInvoker.addCommand(coldCommand);

    // 执行命令
    myInvoker.execCommand();
}

运行:

小爱同学唱歌了
小爱同学讲笑话了
空调制热了
空调制冷了

写在后面

参考文章列表

秒懂设计模式之命令模式(Command Pattern) 。

你可能感兴趣的:(设计模式,设计模式,命令模式)