Command Pattern命令设计模式介绍和应用场景

DBC 681 0
  • 命令设计模式(Command Pattern)
    • 请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的对象,并把该命令传给相应的对象 执行命令,属于行为型模式
    • 命令模式是一种特殊的策略模式,体现的是多个策略执行的问题,而不是选择的问题

 

  • 应用场景
    • 只要是你认为是命令的地方,就可以采用命令模式
    • 日常每个界面、按钮、键盘 事件操作都是 命令设计模式 

 

  • 角色
    • 抽象命令(Command):需要执行的所有命令都在这里声明
    • 具体命令(ConcreteCommand):定义一个接收者和行为之间的弱耦合,实现execute()方法,负责调用接收者的相应操作,execute()方法通常叫做执行方法。

     

    • 接受者(Receiver):负责具体实施和执行一个请求,干活的角色,命令传递到这里是应该被执行的,实施和执行请求的方法叫做行动方法

     

    • 请求者(Invoker):负责调用命令对象执行请求,相关的方法叫做行动方法
    • 客户端(Client):创建一个具体命令(ConcreteCommand)对象并确定其接收者。
  • Command Pattern命令设计模式介绍和应用场景插图

伪代码实现
//接受者,命令执行者
public class Receiver {
    public void doSomething() {
        System.out.println("Receiver---doSomething");
    }
}
​
​
//抽象命令
public interface Command {
​
    /**
     * 执行动作
     */
    void execute();
}
​
//具体命令
public class ConcreteCommand implements Command {
    /**
     * 对哪个receiver类进行命令处理
     */
    private Receiver receiver;
​
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }
​
    /**
     * 必须实现一个命令
     */
    @Override
    public void execute() {
        System.out.println("ConcreteCommand---execute");
        receiver.doSomething();
    }
​
}
​
//请求者
public class Invoker {
​
    private Command command;
​
    public Invoker(Command command){
​
        this.command = command;
    }
​
    /**
     * 执行命令
     */
    public void action(){
        this.command.execute();
    }
}
​
​
//使用
public static void main(String[] args) {
        //创建接收者
        Receiver receiver = new Receiver();
        //创建命令对象,设定它的接收者
        Command command = new ConcreteCommand(receiver);
​
      //创建请求者,把命令对象设置进去
        Invoker invoker = new Invoker(command);
        //执行方法
        invoker.action();
​
    }
业务需求

小滴课堂老王-搬新家了,他想实现智能家居,开发一个app,可以控制家里的家电,比如控制空调的开关、加热、制冷 等功能

利用命令设计模式,帮老王完成这个需求,注意:动作请求者就是手机app, 动作的执行者是家电的不同功能

小例子——结构图Command Pattern命令设计模式介绍和应用场景插图2
public class AppInvoker {


    private Command onCommand;
    private Command offCommand;

    private Command coolCommand;
    private Command warmCommand;


    public void setOnCommand(Command onCommand) {
        this.onCommand = onCommand;
    }

    public void setOffCommand(Command offCommand) {
        this.offCommand = offCommand;
    }

    public void setCoolCommand(Command coolCommand) {
        this.coolCommand = coolCommand;
    }

    public void setWarmCommand(Command warmCommand) {
        this.warmCommand = warmCommand;
    }


    /**
     * 开机
     */
    public void on(){
        onCommand.execute();
    }

    /**
     * 关机
     */
    public void off(){
        offCommand.execute();
    }

    public void warm(){
        warmCommand.execute();
    }

    public void cool(){
        coolCommand.execute();
    }

}
public interface Command {

    /**
     * 执行动作
     */
    void execute();

}
public class ConditionReceiver {

    public void on(){
        System.out.println("空调开启了");
    }

    public void off(){
        System.out.println("空调关闭了");
    }

    public void cool(){
        System.out.println("空调开始制冷");
    }

    public void warm(){
        System.out.println("空调开始制暖");
    }
}
public class CoolCommand implements Command{

    /**
     * 对哪个receiver 进行命令处理
     */
    private ConditionReceiver receiver;

    public CoolCommand(ConditionReceiver receiver){
        this.receiver = receiver;
    }

    /**
     * 必须实现一个命令的调用
     */
    @Override
    public void execute() {

        System.out.println("CoolCommand -> execute");
        receiver.cool();

    }
}
public class OffCommand implements Command{

    /**
     * 对哪个receiver 进行命令处理
     */
    private ConditionReceiver receiver;

    public OffCommand(ConditionReceiver receiver){
        this.receiver = receiver;
    }

    /**
     * 必须实现一个命令的调用
     */
    @Override
    public void execute() {

        System.out.println("OffCommand -> execute");
        receiver.off();

    }
}
public class OnCommand implements Command{

    /**
     * 对哪个receiver 进行命令处理
     */
    private ConditionReceiver receiver;

    public OnCommand(ConditionReceiver receiver){
        this.receiver = receiver;
    }

    /**
     * 必须实现一个命令的调用
     */
    @Override
    public void execute() {

        System.out.println("OnCommand -> execute");
        receiver.on();

    }
}
public class WarmCommand implements Command{

    /**
     * 对哪个receiver 进行命令处理
     */
    private ConditionReceiver receiver;

    public WarmCommand(ConditionReceiver receiver){
        this.receiver = receiver;
    }

    /**
     * 必须实现一个命令的调用
     */
    @Override
    public void execute() {

        System.out.println("WarmCommand -> execute");
        receiver.warm();

    }
}
public class Main {

    public static void main(String[] args) {

        //创建接受者,空调就是接受者
        ConditionReceiver receiver = new ConditionReceiver();

        //创建命令对象,设置命令的接受者
        Command onCommand = new OnCommand(receiver);
        Command offCommand = new OffCommand(receiver);
        Command coolCommand = new CoolCommand(receiver);
        Command warmCommand = new WarmCommand(receiver);

        //创建请求者,把命令对象设置进去,app就是请求发起者
        AppInvoker appInvoker = new AppInvoker();
        appInvoker.setOnCommand(onCommand);
        appInvoker.setOffCommand(offCommand);
        appInvoker.setCoolCommand(coolCommand);
        appInvoker.setWarmCommand(warmCommand);

        appInvoker.on();
        System.out.println();

        appInvoker.cool();
        System.out.println();

        appInvoker.warm();
        System.out.println();

        appInvoker.off();



    }
}
控制台输出——Command Pattern命令设计模式介绍和应用场景插图4
  • 优点
    • 调用者角色与接收者角色之间没有任何依赖关系,不需要了解到底是哪个接收者执行,降低了系统耦合度
    • 扩展性强,新的命令可以很容易添加到系统中去。

 

  • 缺点
    • 过多的命令模式会导致某些系统有过多的具体命令类

发表评论 取消回复
表情 图片 链接 代码

分享