Design patterns 命令模式似乎不必要地复杂(我不理解什么?)

Design patterns 命令模式似乎不必要地复杂(我不理解什么?),design-patterns,abstraction,command-pattern,information-hiding,Design Patterns,Abstraction,Command Pattern,Information Hiding,我已经阅读了命令模式,我想我遗漏了一些东西。命令对象的存在是为了抽象出接收方对象的细节。在我看来,我们可以简单地停在这里,保存对命令对象的引用,以便在适当的时间执行适当的方法 那么,为什么需要调用程序呢?这种额外的间接方式有什么好处?我们已经在命令后面隐藏了接收者的细节,那么对客户端隐藏命令的动机是什么呢?好吧,如果你这么说,它看起来相当复杂,但接收者通常根本不需要是对象。它可以仅仅是一个被执行的函数(作为事件)。此外,调用程序不需要是类。它只是触发命令的东西。这也可以是按钮中的事件处理程序 甚

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


那么,为什么需要调用程序呢?这种额外的间接方式有什么好处?我们已经在命令后面隐藏了接收者的细节,那么对客户端隐藏命令的动机是什么呢?

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


甚至总结了几个例子,其中使用了该模式,而实际上不必为调用者和接收者实现完全独立的类。一个例子是向导对话框,其中GUI填充命令对象,Finish按钮触发它。因此,GUI类(您无论如何都拥有)既是客户机又是调用程序。

从我所知,该模式的全部要点是拥有某种命令生成器和某种命令使用者,但允许生成器在使用者不改变的情况下创建或修改命令

该模式将生产者称为“客户机”,消费者称为“调用者”

这是一个OO回调

那么,为什么需要调用程序呢

据我所知,调用程序没有明确的形式。它只是一些接受抽象命令的代码

在我看来,我们可以简单地停在这里,保存对命令对象的引用

如果调用命令以接受或保留对抽象命令的引用在代码中有意义,那么您已经实现了调用器


如果一位代码既是生产者又是消费者,那么命令模式就一文不值。只有当您将抽象命令传递给希望调用它们的对象时,才有价值。

如果您传递的是不同类型的命令,
Invoker
非常有用。您可以使用相同的调用程序来执行不同的具体命令。在另一个节点上,使用
ConcreteCommand
而不是
Invoker
标记
Receiver
允许松耦合。
接收器
可以更改方法的名称(例如,切换到swithcOnTV),如本例所示:

相关职位:

为了理解调用程序的用途,我希望您参考餐厅和汽车服务中心用例

服务员(
调用者
)从其便笺簿上的
客户
处接受订单。然后,
订单
排队等待订单厨师,并到达厨师(
接收者
)进行处理

客户是
客户
。他通过侍者将请求发送给
接收者
,侍者是
调用者
。服务员将命令(本例中的订单)封装在支票上,然后将其放置,创建
ConcreteCommand
对象,即命令本身

接收者将是厨师,在完成相关命令之前发送给他的所有订单的工作后,开始对其进行工作

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

我们已经在命令后面隐藏了接收器的细节

这完全正确,但谁在隐瞒这些细节?这些细节是对谁隐瞒的? 答案是,任何实例化命令实现的人都在进行隐藏,而任何调用命令抽象的人都是隐藏的。显然,这两个动作都由一个对象执行是没有意义的,就像你可以对自己隐藏一些东西一样

因此,
客户端
实例化一个
具体命令
,并将其传递给
调用方
,调用方只知道
命令
接口。实际上,客户端为调用程序执行依赖项注入


还要注意,有不同的方法来实现ConcreteCommand(请参阅)。如果ConcreteCommand有某种机制来动态发现自己的接收者,那么依赖注入可能是不必要的。

我有java示例,这可能有助于理解这些概念:如果同一个对象既是客户机又是调用者,那么它就违背了模式的目的。请参阅我自己的答案和@MerlynMorgan-Graham的答案。@jaco0646部分,当然可以,但取决于应用程序的其余部分。扩展向导的示例,向导基类可以实现基本步骤,包括调用(针对抽象接口),而子代则构造命令。从在表单中执行所有操作,到将该逻辑提取到命令生成器,这是一个进步。所以我不同意它完全违背了模式的目的。但是,是的,在一个绿色领域的场景中,您必须更进一步,才能充分受益于它的各个方面。一个实现基本步骤,同时将其他步骤推迟到后代实现的抽象接口的基类是模板方法模式的定义。这确实是一个有用的模式,但与命令模式有很大不同。Wikipedia中的向导描述(目前)非常模糊,可以通过任意数量的模式来实现。(根据我的经验,Wikipedia通常不擅长设计模式。)