为什么命令模式在面向对象设计中很方便?

发布于 2024-11-14 22:53:45 字数 203 浏览 9 评论 0原文

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

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

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

I don't understand why a Command pattern is convenient in object-oriented design.

Instead of using, e.g. the Command Switch which has a reference to the Lamp class, can't I just create a Switchable abstract class and invoke its methods?

In this way I'm decoupling the invoker and receiver anyway, and I don't have to create a Command object for each receiver class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

迷途知返 2024-11-21 22:53:45

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

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

Your Switchable creates an abstraction between invoker and receiver but they are still coupled (invoker has needs a reference to the receiver). The Command pattern lets you create that decoupling. The invoker says to some intermediate component "Hey I've got this command I'd like to be executed" and then the intermediate thing can dynamically pass that request on to the receiver.

ps... I'm guessing you pulled the Switch example from wikipedia. That's a pretty bad example of why this pattern is useful. Take a look at a better examples.

那请放手 2024-11-21 22:53:45

假设您想要创建一个如下所示的列表:

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

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

Suppose you want to make a list like this:

  • Turn on lamp
  • Set A/C temperature
  • Play "Moon River"

The actions and receivers are all different, so you need an abstraction that is decoupled from all of them. The Command pattern also comes in handy when you want to support undo/redo or similar things.

世界如花海般美丽 2024-11-21 22:53:45

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

  1. 呼叫接收者并告诉他执行任务。
  2. 呼叫认识接收者的第三方,第三方会将消息传递给接收者。

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

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

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

Lets look at it like: When client wants the receiver to execute some task, then client has two options,

  1. Call Receiver and tell him to execute the task.
  2. Call some third party who knows receiver, and third party will pass the message to receiver.

First option looks better, as think of scenario, when there is no waiter to take order in restaurant and you have to go to chef to tell him what you want.

OR suppose you lost your remote and you have to go to TV and manually switch the button.

It provides flexibility so that command can be executed not only in synchronous mode, but also in Asynchronous mode.

无远思近则忧 2024-11-21 22:53:45
You -> Switch -> Light

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

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

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

You -> Switch -> Light

Here the switch decouples you and the light. So it makes it easier to turn on/off lights using switch. this is use (convenience) in using command pattern.

You - Command Invoker
Switch - Command Manager
Command - Turn On/Off
Light - Actual implementer

If command pattern is not there you have to manually put the light in holder when needed and remove it when not needed.

々眼睛长脚气 2024-11-21 22:53:45

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

No. You can not do the same as a command do with the abstraction. In fact every time you can do the work of a pattern and anything else with another way you can do. But when you change the Switcher from concrete to abstract that you must do this for a right design regardless of command pattern, you are only decoupling the client of switcher form its implementation and not decoupling the switcher(i.e Invoker) from Lamp(i.e. Receiver) because at last you must have a reference to Lamp in the concretes of Switcher that is equals to have it in Switcher. Note is here that the Lamp is a concrete and you can not change it to abstract. So when you have a concrete and you are working with it many time and many other attribute, you must use Command Pattern to decouple the Switcher form Lamp by move dependency of Switcher to Lamp inside Command class and depend Switcher to an intermediate class i.e. Command. In addition I think the sample in Wikipedia is very useful.

风吹雨成花 2024-11-21 22:53:45

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

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

例如,为简单的文本编辑器实现命令模式(GOF - 第 2 章)看起来像像这样:

在此处输入图像描述

通过存储一个undoRedoPointer,我们可以实现undo/redo操作通过每次执行命令时增加/减少计数器而不违反对象的封装。这是该命令与备忘录设计模式相结合的结果。

The command pattern offers a structured way of associating user actions with system commands.

By implementing the Command pattern, you can have a structured technique of storing the user's command and thus allow actions such as undo/redo.

For instance, implementing the Command pattern for a simple text editor (GOF - Chapter 2) would look like this:

enter image description here

By storing a undoRedoPointer, we can achieve the undo/redo operation by increasing/decreasing the counter each time a command is executed without violating the object's encapsulation. This is a result of combining the command and the memento design pattern.

云胡 2024-11-21 22:53:45

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

1)保存所有这些命令对象,

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

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

Think of each 'command' object as a live object or task that knows how to perform something by its own. Your invoker is just a queue or list that can

1) hold all these command objects and

2) execute them in order/fashion that you liked to.

This model is so flexible in terms of a handler, isn't it? The invoker can buffer, prioritize or follow any algorithm when performing the tasks.

来世叙缘 2024-11-21 22:53:45

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

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

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

Ctrl+C 操作 -->复制命令 -->复制算法

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

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

I believe through Command Pattern multiple invokers can use the same command. For e.g., In case of editor, copy functionality (or algo) is required to be invoked from command (ctrl+c) or from menu.

So if you wouldn't have implemented command pattern, copy algo would have been tightly coupled with ctrl+c command, and would have been difficult for you to reuse to be invoked from editor menu.

So it looks like this ...

Ctrl+C action --> CopyCommand --> Copy algo

Menu copy command --> CopyCOmmand --> Copy algo

As you can see from above, the source of command is changing, but destination is same (copy algo)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文