为什么我可以使用命令设计模式,我可以轻松地调用所需的方法? [英] Why should I use the command design pattern while I can easily call required methods?

查看:106
本文介绍了为什么我可以使用命令设计模式,我可以轻松地调用所需的方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究命令设计模式,我对使用它的方式感到困惑。我的例子与一个用于打开和关闭灯光的遥控器类有关。

I am studying the command design pattern, and I am quite confused with the way of using it. The example that I have is related to a remote control class that is used to turn lights on and off.

为什么我不应该使用switchOn()/ switchOff() Light类的方法,而不是分别调用switchOn / switchOff方法的类和方法?

Why should I not use the switchOn() / switchOff() methods of Light class rather than having separate classes and methods that eventually call switchOn / switchOff methods?

我知道我的例子很简单>,但这是重点。我无法在互联网上的任何地方找到任何复杂的问题,以查看命令设计模式的确切用法。

如果您知道任何你解决的复杂的现实世界问题可以使用这种设计模式来解决,请与我分享。它帮助我和这个帖子的未来读者更好地了解这种设计模式的用法。感谢

//Command
public interface Command {
  public void execute();
}

//Concrete Command
public class LightOnCommand implements Command {

  //Reference to the light
  Light light;

  public LightOnCommand(Light light) {
    this.light = light;
  }

  public void execute() {
    light.switchOn();        //Explicit call of selected class's method
  }
}

//Concrete Command
public class LightOffCommand implements Command {

  //Reference to the light
  Light light;

  public LightOffCommand(Light light) {
    this.light = light;
  }

  public void execute() {
    light.switchOff();
  }
}

//Receiver
public class Light {
  private boolean on;

  public void switchOn() {
    on = true;
  }

  public void switchOff() {
    on = false;
  }
}

//Invoker
public class RemoteControl {
  private Command command;

  public void setCommand(Command command) {
    this.command = command;
  }

  public void pressButton() {
    command.execute();
  }
}

//Client
public class Client {
  public static void main(String[] args) {
    RemoteControl control = new RemoteControl();
    Light light = new Light();
    Command lightsOn = new LightsOnCommand(light);
    Command lightsOff = new LightsOffCommand(light);

    //Switch on
    control.setCommand(lightsOn);
    control.pressButton();

    //Switch off
    control.setCommand(lightsOff);
    control.pressButton();
  }
}

为什么不能轻松使用代码以下?

 Light light = new Light();
 switch(light.command) {
  case 1:
    light.switchOn();
    break;
  case 2:
    light.switchOff();
    break;
 }


推荐答案

命令模式是指令的执行者根本不需要知道什么是命令,它需要什么上下文信息或它所做的。所有这些都封装在命令中。

The main motivation for using the Command pattern is that the executor of the command does not need to know anything at all about what the command is, what context information it needs on or what it does. All of that is encapsulated in the command.

这样,您可以执行某些操作,例如按顺序执行的依赖于其他项目的命令列表,分配给某些触发事件等。

This allows you to do things such as have a list of commands that are executed in order, that are dependent on other items, that are assigned to some triggering event etc.

在你的例子中,你可以有其他类(例如空调)有自己的命令(例如 Turn Thermostat Up Turn Thermostat Down )。任何这些命令都可以分配给一个按钮,或者当满足某些条件时触发,而不需要任何知道该命令。

In your example, you could have other classes (e.g. Air Conditioner) that have their own commands (e.g. Turn Thermostat Up, Turn Thermostat Down). Any of these commands could be assigned to a button or triggered when some condition is met without requiring any knowledge of the command.

所以,总而言之,模式封装了所需的一切采取行动,并允许执行行动完全独立于任何上下文发生。如果这不是您的要求,那么该模式对您的问题空间可能没有帮助。

So, in summary, the pattern encapsulates everything required to take an action and allows the execution of the action to occur completely independently of any of that context. If that is not a requirement for you then the pattern is probably not helpful for your problem space.

以下是一个简单的用例:

Here's a simple use case:

interface Command {
    void execute();
}

class Light {
    public Command turnOn();
    public Command turnOff();
}

class AirConditioner {
    public Command setThermostat(Temperature temperature);
}

class Button {
    public Button(String text, Command onPush);
}

class Scheduler {
    public void addScheduledCommand(Time timeToExecute, Command command);
}

然后,您可以执行以下操作:

Then you can do things such as:

new Button("Turn on light", light.turnOn());
scheduler.addScheduledCommand(new Time("15:12:07"), airCon.setThermostat(27));
scheduler.addScheduledCommand(new Time("15:13:02"), light.turnOff());

正如您可以看到 Button Scheduler 根本不需要知道任何命令。 Scheduler 是一个可能包含命令集合的类的示例。

As you can see the Button and Scheduler don't need to know anything at all about the commands. Scheduler is an example of a class that might hold a collection of commands.

还要注意,在Java 8功能接口和方法引用使得这种类型的代码更加简洁:

Note also that in Java 8 functional interfaces and method references have made this type of code even neater:

@FunctionalInterface
interface Command {
    void execute();
}

public Light {
    public void turnOn();
}

new Button("Turn On Light", light::turnOn);   

现在转成命令的方法甚至不需要知道命令 - 只要他们具有正确的签名,您可以通过引用该方法静静地创建一个匿名命令对象。

Now the methods that are turned into commands don't even need to know about commands - as long as they have the correct signature you can quietly create a anonymous command object by referencing the method.

这篇关于为什么我可以使用命令设计模式,我可以轻松地调用所需的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆