17

我不明白为什么命令模式在面向对象设计中很方便。

而不是使用,例如Switch引用Lamp类的命令,我不能只创建一个Switchable抽象类并调用它的方法吗?

通过这种方式,无论如何我都将调用者和接收者解耦,并且我不必为每个接收者类创建一个 Command 对象。

4

8 回答 8

13

Switchable在调用者和接收者之间创建了一个抽象,但它们仍然是耦合的(调用者需要对接收者的引用)。命令模式允许您创建这种解耦。调用者对一些中间组件说“嘿,我有这个命令我想执行”,然后中间的东西可以动态地将该请求传递给接收者。

ps ...我猜你从维基百科中提取了 Switch 示例。这是为什么这种模式有用的一个非常糟糕的例子。看一个更好的例子

于 2011-06-09T13:09:58.623 回答
9

假设你想制作一个这样的列表:

  • 打开灯
  • 设置空调温度
  • 播放“月亮河”

动作和接收者都是不同的,所以你需要一个与它们解耦的抽象。当您想要支持撤消/重做或类似的事情时,命令模式也会派上用场。

于 2011-06-09T13:11:57.493 回答
7

让我们看一下:当客户端希望接收者执行某些任务时,客户端有两个选择,

  1. 呼叫 Receiver 并告诉他执行任务。
  2. 打电话给知道接收者的第三方,第三方将消息传递给接收者。

第一个选项看起来更好,想想场景,当餐厅没有服务员点菜,你必须去找厨师告诉他你想要什么。

或者假设您丢失了遥控器,您必须去电视并手动切换按钮。

它提供了灵活性,因此命令不仅可以在同步模式下执行,还可以在异步模式下执行。

于 2013-08-14T20:30:03.923 回答
6
You -> Switch -> Light

在这里,开关将您和灯光解耦。因此,使用开关可以更轻松地打开/关闭灯光。这是使用命令模式的用途(方便)。

你 - 命令调用者
开关 - 命令管理器
命令 - 打开/关闭
灯 - 实际实施者

如果没有命令模式,您必须在需要时手动将灯放入支架中,并在不需要时将其移除。

于 2015-10-08T06:25:49.783 回答
1

不,你不能像命令一样对抽象做同样的事情。事实上,每次你都可以用另一种方式来完成模式和其他任何事情。但是,当您将切换器从具体更改为抽象时,无论命令模式如何,您都必须为正确的设计执行此操作,您只是将切换器的客户端与其实现解耦,而不是将切换器(即调用者)与灯(即接收器)解耦因为最后你必须在 Switcher 的具体实现中引用 Lamp,这等于在 Switcher 中拥有它。请注意,Lamp 是具体的,您不能将其更改为抽象的。所以当你有一个混凝土并且你使用它很多时间和许多其他属性时,您必须使用命令模式通过将 Switcher 的依赖关系移动到 Command 类中的 Lamp 并将 Switcher 依赖于中间类(即 Command)来将 Switcher 与 Lamp 解耦。另外我认为维基百科中的示例非常有用。

于 2016-01-25T14:03:52.753 回答
1

命令模式提供了一种将用户操作系统命令相关联的结构化方式。

通过实现命令模式,您可以拥有存储用户命令的结构化技术,从而允许诸如撤消/重做之类的操作。

例如,为一个简单的文本编辑器(GOF - 第 2 章)实现命令模式将如下所示:

在此处输入图像描述

通过存储 a undoRedoPointer,我们可以在不违反对象封装的情况下,每次执行命令时通过增加/减少计数器来实现撤消/重做操作。这是结合命令和备忘录设计模式的结果。

于 2017-04-15T20:34:10.257 回答
0

将每个“命令”对象视为知道如何自行执行某事的活动对象或任务。您的调用者只是一个队列或列表,可以

1)持有所有这些命令对象和

2)按照您喜欢的顺序/方式执行它们。

这个模型在处理程序方面非常灵活,不是吗?调用者在执行任务时可以缓冲、优先排序或遵循任何算法。

于 2016-01-04T09:11:51.020 回答
0

我相信通过命令模式,多个调用者可以使用相同的命令。例如,在编辑器的情况下,需要从命令 (ctrl+c) 或菜单调用复制功能(或算法)。

因此,如果您没有实现命令模式,则复制算法将与 ctrl+c 命令紧密耦合,并且您很难重用以从编辑器菜单中调用。

所以它看起来像这样......

Ctrl+C 操作 --> CopyCommand --> 复制算法

菜单复制命令 --> CopyCOMmand --> 复制算法

从上面可以看出,命令的来源正在改变,但目的地是相同的(复制算法)

于 2019-04-20T07:53:59.497 回答