命令模式似乎不必要复杂(我不明白的是什么?)

时间:2011-05-19 19:52:42

标签: design-patterns abstraction command-pattern information-hiding

我已经阅读了命令模式,我想我错过了一些东西。 Command对象的存在是为了抽象出Receiver对象的细节。在我看来,我们可以简单地停在这里,并保持对Command对象的引用,以便在适当的时间执行适当的方法。

那么,为什么需要Invoker呢?这种额外的间接提供了什么优势?我们已经隐藏了命令背后的接收器的细节,那么命令随后被客户隐藏的动机是什么?

4 个答案:

答案 0 :(得分:4)

如果您传递的是不同类型的命令,Invoker很有用。您可以使用相同的Invoker来执行不同的具体命令。在其他节点上,使用Receiver而不是ConcreteCommand标记Invoker可以实现松散耦合。 Receiver可能会更改方法的名称(例如switchOn to swithcOnTV),如下例所示:

相关文章:Using Command Design pattern

要了解Invoker的目的,我希望您在餐厅&amp ;;上提及此article。汽车服务中心用例。

服务员(Invoker)接受他垫上Customer的订单。然后Order排队等待订单烹饪并送到厨师(Receiver)进行处理。

客户端是Customer。他通过服务员ReceiverInvoker发送请求。服务员通过在命令上写入命令来封装命令(在这种情况下为顺序),然​​后放置它,创建ConcreteCommand对象,这是命令本身。

Receiver将成为厨师,在完成对相关命令之前发送给他的所有订单的工作后,开始对其进行处理。

该示例的另一个值得注意的方面是,订单的打击垫不仅支持菜单中的订单,因此它可以支持命令来烹饪许多不同的项目。

答案 1 :(得分:3)

好吧,如果你这样说,它似乎相当复杂,但通常接收器根本不需要成为一个对象。它可以只是一个执行的函数(作为一个事件)。此外,调用者不需要是一个类。这只是触发命令的事情。这也可以是按钮中的事件处理程序。

偶数Wikipedia总结了几个例子,其中使用了这种模式而实际上不必为调用者和接收者实现完整的单独类。一个示例是向导对话框,其中GUI填充命令对象,完成按钮触发它。因此,GUI类(无论如何)都是客户端和调用者。

答案 2 :(得分:3)

据我所知,模式的重点是拥有某种命令生成器和某种命令使用者,但允许生产者在不改变消费者的情况下创建或修改命令。

模式将生产者称为“客户”,将消费者称为“祈求者”。

这是一个OO回调。

  

那么,为什么需要Invoker

all the examples on Wikipedia我所知,调用者没有明确的形式。它只是一些接受抽象命令的代码。

  

在我看来,我们可以简单地停在这里,并保持对Command对象的引用

如果在代码中调用命令来接受或保持对抽象命令的引用,那么你已经实现了调用者。

如果一位代码既是生产者又是消费者,那么命令模式就毫无价值。将抽象命令传递给想要调用它们的东西时,这是值得的。

答案 3 :(得分:2)

  

我们已经在命令后面隐藏了接收方的详细信息,

那是完全正确的,但是谁隐藏了这些细节,又隐藏了谁? 答案是实例化Command implementation 的任何人都在进行隐藏,而调用Command abstraction 的人都被隐藏了。显然,由一个对象执行这两个动作是没有任何意义的,而不仅仅是您可以对自己隐藏一些东西。

因此,Client实例化了ConcreteCommand并将其传递给Invoker,后者只知道Command接口。实际上,客户端为调用程序执行依赖项注入。

还要注意,有多种方法可以实现ConcreteCommand(请参见https://stackoverflow.com/a/35617012/1371329)。如果ConcreteCommand具有某种机制来动态发现其自己的Receiver,则可能不需要依赖注入。