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

时间:2011-06-09 13:01:22

标签: oop design-patterns command-pattern

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

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

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

8 个答案:

答案 0 :(得分:13)

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

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

答案 1 :(得分:9)

假设您要制作如下列表:

  • 打开灯泡
  • 设置A / C温度
  • 播放“月亮河”

动作和接收器都是不同的,因此您需要一个与所有动作分离的抽象。当你想支持撤销/重做或类似事情时,Command模式也会派上用场。

答案 2 :(得分:7)

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

  
      
  1. 致电接收人并告诉他执行任务。
  2.   
  3. 呼叫知道接收方的第三方,第三方将消息传递给接收方。
  4.   

第一个选项看起来更好,就像想象一样,当没有服务员在餐厅接受订单而你必须去厨师告诉他你想要什么。

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

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

答案 3 :(得分:5)

Sub maxtest3()

Dim L As Integer, La As Integer, Lb As Integer, Lc As Integer, Ld As Integer
Dim a As Variant
L = 0
La = 0
Lb = 0
Lc = 0
Ld = 0


For Each a In Range("A1:A20")
If a.Value > L Then
    L = a.Value
        Else
        If a.Value > La Then
        La = a.Value
            Else
            If a.Value > Lb Then
            Lb = a.Value
                Else
                If a.Value > Lc Then
                Lc = a.Value
                    Else
                    If a.Value > Ld Then
                    Ld = a.Value
                        Else
                    End If
                End If
            End If
        End If
    End If
Next
                MsgBox (L & " " & La & " " & Lb & " " & Lc & " " & Ld)
End Sub

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

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

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

答案 4 :(得分:1)

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

答案 5 :(得分:1)

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

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

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

enter image description here

通过存储undoRedoPointer,我们可以通过在每次执行命令时增加/减少计数器来实现撤销/重做操作,而不会违反对象的封装。这是将命令与memento design pattern组合在一起的结果。

答案 6 :(得分:0)

将每个“命令”对象视为一个知道如何通过自己的方式执行某些操作的实时对象或任务。你的调用者只是一个可以

的队列或列表

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

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

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

答案 7 :(得分:0)

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

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

所以看起来像这样...

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

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

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