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

Oop 为什么命令模式在面向对象设计中很方便?,oop,design-patterns,command-pattern,Oop,Design Patterns,Command Pattern,我不明白为什么命令模式在面向对象设计中很方便 我不能创建一个可切换的抽象类并调用它的方法,而不是使用,例如,引用了Lamp类的命令Switch 通过这种方式,我将调用方和接收方解耦,并且我不必为每个接收方类创建命令对象。您的可切换的在调用方和接收方之间创建了一个抽象,但它们仍然是耦合的(调用方需要引用接收方)。命令模式允许您创建这种解耦。调用程序对某个中间组件说“嘿,我已经得到了这个我想要执行的命令”,然后中间组件可以动态地将该请求传递给接收方 ps。。。我猜你是从维基百科中提取了开关示例。这是

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

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


通过这种方式,我将调用方和接收方解耦,并且我不必为每个接收方类创建命令对象。

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


ps。。。我猜你是从维基百科中提取了开关示例。这是一个很糟糕的例子,说明了为什么这个模式很有用。请看一个。

假设您想制作一个如下列表:

  • 开灯
  • 设置空调温度
  • 玩“月亮河”

动作和接收者都是不同的,因此您需要一个与它们分离的抽象。当您希望支持撤消/重做或类似操作时,命令模式也很方便。

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

  • 给接受者打电话,告诉他执行任务
  • 打电话给认识接收者的第三方,第三方会将消息传递给接收者 第一种选择看起来更好,就像想象的那个样,当餐厅里并没有服务员点菜时,你们必须去厨师那个里告诉他你们想要什么

    或者假设你的遥控器丢了,你不得不去看电视并手动切换按钮

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

    You -> Switch -> Light
    
    在这里,开关将你和灯分离。因此,使用开关可以更轻松地打开/关闭灯。这是使用命令模式时的使用(方便)

    您-命令调用程序
    开关-命令管理器
    命令-打开/关闭
    轻-实际实现者


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

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

    1) 保留所有这些命令对象并

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


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

    否。您不能像命令一样处理抽象。事实上,每一次你都可以用另一种方法来完成一个模式的工作。但是,当您将切换器从具体更改为抽象时,无论命令模式如何,您都必须这样做才能实现正确的设计,您只是将切换器的客户端从其实现中解耦,而不是将切换器(即调用器)从Lamp(即接收器)中解耦因为最后你们必须在切换器的混凝土中有一个关于灯的参考,这等于在切换器中有它。请注意,这里的灯是一个具体的,你不能改变它的抽象。因此,当您有一个具体的,并且您正在使用它很多次和许多其他属性时,您必须使用命令模式,通过将切换器的依赖项移动到命令类内的Lamp,并将切换器依赖于中间类,即Command,来将切换器与Lamp解耦。此外,我认为Wikipedia中的示例非常有用。

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

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

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


    通过存储
    undoRedoPointer
    ,我们可以通过每次执行命令时增加/减少计数器来实现undo/redo操作,而不会破坏对象的封装。这是命令和命令组合的结果。

    我相信通过命令模式,多个调用程序可以使用同一个命令。例如,对于编辑器,需要从命令(ctrl+c)或菜单调用复制功能(或algo)

    所以,若您并没有实现命令模式,那个么copy algo将与ctrl+c命令紧密耦合,并且对于您来说很难重用以从编辑器菜单调用

    所以看起来像这样

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

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


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

    Ok,在撤消/重做上下文中,我理解。但在其他情况下,为什么要将调用程序和接收器解耦?是因为要保持代码的可维护性,并使调用程序更加可重用?还是有更多的实际优势?+1为历史机制和复合指令-两个经典。命令模式将调用行为与调用细节分离。从调用者的角度来看,只有ever Command.execute(),“do”和“how”是分开的。@Patrick,这里使用的切换示例中的遥控器,或者服务员拿着客户的订单由厨师处理,这可能会有所帮助。谢谢您提供了这个示例。但是,我仍然不认为在命令中而不是在调用程序中引用接收方有什么好处。换句话说,为什么要去耦合