我不明白为什么命令模式在面向对象设计中很方便。
而不是使用,例如Switch
引用Lamp
类的命令,我不能只创建一个Switchable
抽象类并调用它的方法吗?
通过这种方式,无论如何我都将调用者和接收者解耦,并且我不必为每个接收者类创建一个 Command 对象。
我不明白为什么命令模式在面向对象设计中很方便。
而不是使用,例如Switch
引用Lamp
类的命令,我不能只创建一个Switchable
抽象类并调用它的方法吗?
通过这种方式,无论如何我都将调用者和接收者解耦,并且我不必为每个接收者类创建一个 Command 对象。
您Switchable
在调用者和接收者之间创建了一个抽象,但它们仍然是耦合的(调用者需要对接收者的引用)。命令模式允许您创建这种解耦。调用者对一些中间组件说“嘿,我有这个命令我想执行”,然后中间的东西可以动态地将该请求传递给接收者。
ps ...我猜你从维基百科中提取了 Switch 示例。这是为什么这种模式有用的一个非常糟糕的例子。看一个更好的例子。
假设你想制作一个这样的列表:
动作和接收者都是不同的,所以你需要一个与它们解耦的抽象。当您想要支持撤消/重做或类似的事情时,命令模式也会派上用场。
让我们看一下:当客户端希望接收者执行某些任务时,客户端有两个选择,
- 呼叫 Receiver 并告诉他执行任务。
- 打电话给知道接收者的第三方,第三方将消息传递给接收者。
第一个选项看起来更好,想想场景,当餐厅没有服务员点菜,你必须去找厨师告诉他你想要什么。
或者假设您丢失了遥控器,您必须去电视并手动切换按钮。
它提供了灵活性,因此命令不仅可以在同步模式下执行,还可以在异步模式下执行。
You -> Switch -> Light
在这里,开关将您和灯光解耦。因此,使用开关可以更轻松地打开/关闭灯光。这是使用命令模式的用途(方便)。
你 - 命令调用者
开关 - 命令管理器
命令 - 打开/关闭
灯 - 实际实施者
如果没有命令模式,您必须在需要时手动将灯放入支架中,并在不需要时将其移除。
不,你不能像命令一样对抽象做同样的事情。事实上,每次你都可以用另一种方式来完成模式和其他任何事情。但是,当您将切换器从具体更改为抽象时,无论命令模式如何,您都必须为正确的设计执行此操作,您只是将切换器的客户端与其实现解耦,而不是将切换器(即调用者)与灯(即接收器)解耦因为最后你必须在 Switcher 的具体实现中引用 Lamp,这等于在 Switcher 中拥有它。请注意,Lamp 是具体的,您不能将其更改为抽象的。所以当你有一个混凝土并且你使用它很多时间和许多其他属性时,您必须使用命令模式通过将 Switcher 的依赖关系移动到 Command 类中的 Lamp 并将 Switcher 依赖于中间类(即 Command)来将 Switcher 与 Lamp 解耦。另外我认为维基百科中的示例非常有用。
将每个“命令”对象视为知道如何自行执行某事的活动对象或任务。您的调用者只是一个队列或列表,可以
1)持有所有这些命令对象和
2)按照您喜欢的顺序/方式执行它们。
这个模型在处理程序方面非常灵活,不是吗?调用者在执行任务时可以缓冲、优先排序或遵循任何算法。
我相信通过命令模式,多个调用者可以使用相同的命令。例如,在编辑器的情况下,需要从命令 (ctrl+c) 或菜单调用复制功能(或算法)。
因此,如果您没有实现命令模式,则复制算法将与 ctrl+c 命令紧密耦合,并且您很难重用以从编辑器菜单中调用。
所以它看起来像这样......
Ctrl+C 操作 --> CopyCommand --> 复制算法
菜单复制命令 --> CopyCOMmand --> 复制算法
从上面可以看出,命令的来源正在改变,但目的地是相同的(复制算法)