设计模式(11)-----命令设计模式

Posted qingruihappy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式(11)-----命令设计模式相关的知识,希望对你有一定的参考价值。

把命令封装成一个命令对象,使请求者和被请求者完全解耦。我们先来看一下类图:

技术分享图片

下面我们来看代码

Invoker==SimpleRemoteControl

public class SimpleRemoteControl {

    Command slot;// 有一个插槽持有命令,而这个命令控制着设备

    public SimpleRemoteControl() {

    }

    public void setCommand(Command command) {

         slot = command;     }

    public void buttonWasPressed() {

         slot.execute();

    }

}

command==Command

public interface Command {     public void execute();

}

concreteCommand==LightOffCommand

public class LightOffCommand implements Command {

    Light light;

 

    public LightOffCommand(Light light) {

         this.light = light;

    }

 

    public void execute() {

         light.off();

    }

}

concreteCommand==LightOnCommand

public class LightOnCommand implements Command {

    Light light;

 

    public LightOnCommand(Light light) {

         this.light = light;

    }

 

    public void execute() {

         light.on();

    }

}

concreteCommand==GarageDoorOpenCommand

public class GarageDoorOpenCommand implements Command {     GarageDoor garageDoor;

    public GarageDoorOpenCommand(GarageDoor garageDoor) {

         this.garageDoor = garageDoor;

    }

    public void execute() {

         garageDoor.up();

    }

}

recevier==Light

public class Light {

    public Light() {

    }

 

 

 

 

 

 

}

public void on() {

    System.out.println("Light is on");

}

public void off() {

    System.out.println("Light is off");

}

client==Test

  • @说明: 不解耦的设计就是按下灯开的开关,灯开了,我按下灯灭的操作灯灭了。
  • 按下车开的开关,车开了,按下车停的操作,车停了。现在开关是两个,并且每个开关有两个命令。

*

  • 解构的设计就是我不知道我现在开关是谁的开关,你告诉我说我是灯的开关,并且是灯开的指令,我就是开灯的命名我就把灯打开了,
  • 你告诉我说是灯灭的命令,我就把灯灭了; 你告诉我说我是车的开关,我按下开关,你告诉我说开车的指令,我就开车了,你告诉我说是停车的指令我就停车了

*

  • 那解耦的设计它是如何实现的呢, 一:告诉我我是谁,并且是什么指令 1.1,有一个灯开灯灭的灯的实例 1.2,把灯传给一个一个灯开的命令对象。
  • 1.3,让后把灯开的命令对象给开关。 1.4,我按下开关等就开了。
  • 补充:这里面需要注意的地方就是开关是不知道控制谁的,定义好的固定的方法excute()
  • 好了,你先在告诉我说我现在是灯开的命令对象(LightOnCommand),那我就去灯开的命令对象里面去看一下
  • LightOnCommand.execute 到里面一看果然是灯开的指令light.on()

*

  • 二:我按下开关

*

*

  • 开关==遥控器==调用者

*

  • 我们接着再来梳理一下:
  • 站在调用者(遥控器)的角度:没给我命令之前(命令对象)我不知道我控制的是谁,我控制谁的什么命令。不想以前,上来我就确定我是灯的开关,我是车的开关。
  • 站在接受者(车,灯)的角度:我现在每一条指令都会封装成一条命令(命令对象)。不想以前,我有许多的指令在里面。
  • 站在两者解耦联系的角度:接受者封装一条命令(命名对象)给调用者,调用者确定了命令对象之后根据已经约定好的方法,去命令对象中找到这个方法,
  • 让后在到接受者中去执行相应的指令。

*

*

  • 在来捋一下,现在遥控器不知道自己是谁,也不知道自己要执行谁的什么命令,只有你告诉我我是谁,并通过约定俗成的方法调用已经知道了谁的
  • 约定俗称的方法,来确定下来我要执行什么命令。

 

  • 套到代码里面就是现在遥控器不知道自己是谁,也不知道要执行什么样的命令,现在你告诉我说我是灯开对象(LightOnCommand),
  • 我就根据我定义的方法(execute),去等开的对象中找一样的方法,果然够被我找到了

    (execute),这个方法告诉说去执行light.on

  • 的命令吧,我现在就把灯打开了。 所以说在命令对象中一定要有和遥控器一样的方法。这也充分发挥了面向借口编程的作用。

    *

  • 相当于以前我就知道我是灯的开关,而且一旦确定就不能变化了。不可能变成车的开关了。 * 现在是我不知道我是谁的开关,你告诉我我是谁的开关我就是谁的开关,可以随意的切花的。

    *

  • 在这里命令模式主要就是针对的这个开关,把请求封装成对象,以便使用不同的请求来参数化其它的对象(定义)

    *

    *

  • 注意了:一般情况下我们常见的是聪明的命令设计模式:就是说命令对象直接完成一个请求,而不是传递一个实例。
  • 以开灯来说,常见的是我们不在LightOnCommand命令对象中是不传light {new
  • LightOnCommand(light)}的,而是直接在LightOnCommand.excute方法中进行对light的操作的。
  • 但是这种常见的聪明的命令模式是没有我们传统上讲的傻瓜式的命令设计模式解耦性好的。

    */

    public class Test {

        public static void main(String[] args) {

             // 调用者 遥控器 把请求封装成一个对象,按下开关请命令对象去做相应的工作,遥控器并不知道工作内容是什么

             // 只要有这个命令能和正确的对象进行沟通。

             SimpleRemoteControl remote = new SimpleRemoteControl();

             // 接受者 厂家给的实例

             Light light = new Light();

             // 创建一个命令,然后将接受者给它,命令对象,命令对象控制接受者

             LightOnCommand lightOn = new LightOnCommand(light);

             GarageDoor garageDoor = new GarageDoor();

             GarageDoorOpenCommand garageOpen = new GarageDoorOpenCommand(garageDoor);

             // 把命令传给调用者

             remote.setCommand(lightOn);

             // 模拟按下按钮

             remote.buttonWasPressed();

             remote.setCommand(garageOpen);

             remote.buttonWasPressed();

}

}

技术分享图片

kk

以上是关于设计模式(11)-----命令设计模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式-行为型模式,命令模式(11)

2021-12-11 WPF面试题 WPF中的命令设计模式是什么

设计模式14命令模式

命令模式

2017.11.12

命令模式 - 设计模式 - PHP版