我已经阅读了命令模式,我想我错过了一些东西。Command 对象的存在是为了抽象出 Receiver 对象的细节。在我看来,我们可以简单地停在这里,并持有对 Command 对象的引用以在适当的时间执行适当的方法。
那么,为什么需要调用者呢?这个额外的间接提供了什么好处?我们已经将 Receiver 的详细信息隐藏在了 Command 后面,那么 Command 对客户端也隐藏起来的动机是什么?
我已经阅读了命令模式,我想我错过了一些东西。Command 对象的存在是为了抽象出 Receiver 对象的细节。在我看来,我们可以简单地停在这里,并持有对 Command 对象的引用以在适当的时间执行适当的方法。
那么,为什么需要调用者呢?这个额外的间接提供了什么好处?我们已经将 Receiver 的详细信息隐藏在了 Command 后面,那么 Command 对客户端也隐藏起来的动机是什么?
如果您传递不同类型的命令,Invoker
这很有用。您可以使用相同的 Invoker 来执行不同的具体命令。在不同的节点上,Receiver
使用ConcreteCommand
而不是标记Invoker
允许松散耦合。可能会更改方法的Receiver
名称(例如 switchOn 到 swithcOnTV),如下例所示:
相关文章:使用命令设计模式
要了解其目的Invoker
,我希望您参考这篇关于餐厅和汽车服务中心用例的文章。
服务员 ( Invoker
) 从Customer
他的垫子上点菜。然后Order
排队等待厨师订单并到达Receiver
处理它的厨师 ( )。
客户端是Customer
. Receiver
他通过服务员将他的请求发送给服务员Invoker
。服务员通过将命令(在这种情况下为订单)写在支票上来封装命令,然后放置它,创建ConcreteCommand
作为命令本身的对象。
将Receiver
是厨师,在完成有关命令之前发送给他的所有订单的工作后,开始工作。
该示例的另一个值得注意的方面是订单面板不仅支持来自菜单的订单,因此它可以支持烹饪许多不同项目的命令。
好吧,如果你这么说,它看起来很复杂,但通常接收器根本不需要是一个对象。它可以不仅仅是一个被执行的函数(作为一个事件)。此外,调用者不需要是一个类。它只是触发命令的东西。这也可以是按钮中的事件处理程序。
甚至Wikipedia也总结了几个使用此模式的示例,而实际上不必为调用者和接收者实现完整的单独类。一个示例是向导对话框,其中 GUI 填充命令对象,并且完成按钮触发它。所以那个 GUI 类(无论如何你都有)既是客户端又是调用者。
据我所知,该模式的重点是拥有某种命令生产者和某种命令消费者,但允许生产者在不改变消费者的情况下创建或修改命令。
该模式将生产者称为“客户”,将消费者称为“调用者”。
这是一个OO回调。
那么,为什么需要调用者
据我从Wikipedia 上的所有示例中可以看出,调用者没有明确的形式。它只是一些接受抽象命令的代码。
在我看来,我们可以简单地停在这里,并持有对 Command 对象的引用
如果在您的代码中调用命令以接受或保持对抽象命令的引用的事物有意义,那么您已经实现了调用程序。
如果一段代码既是生产者又是消费者,那么命令模式毫无价值。仅当您将抽象命令传递给想要调用它们的东西时才值得。
我们已经在命令后面隐藏了接收者的详细信息,
这是完全正确的,但是谁在隐藏这些细节,又是从谁那里隐藏的呢?答案是,谁实例化了 Command实现,谁就在隐藏,谁调用了 Command抽象,谁就被隐藏了。显然,这两个动作都由一个对象执行是没有意义的,就像你可以对自己隐藏一些东西一样。
因此,Client
实例化 aConcreteCommand
并将其传递给Invoker
只知道Command
接口的 。实际上,客户端为调用者执行依赖注入。
另请注意,实现 ConcreteCommand 有不同的方法(请参阅https://stackoverflow.com/a/35617012/1371329)。如果 ConcreteCommand 有某种机制可以动态发现自己的 Receiver,则可能不需要依赖注入。