命令模式 - 目的?

时间:2010-12-02 11:55:40

标签: c# c++ design-patterns

阅读本文后:http://sourcemaking.com/design_patterns/command

我仍然不太明白为什么我们需要这个。

5 个答案:

答案 0 :(得分:14)

这个想法是,如果命令被封装为对象,那么这些命令可以被捕获,存储,排队,重放等。

它还使命令更容易知道如何撤消自身(即执行反向操作),这样如果处理命令,它可以存储在列表中,然后以相反的顺序“撤消”以恢复命令完成前的状态。

它还将命令的发送者与接收者分离。这可以允许多个事物生成相同的命令(例如菜单项和按钮),它们将以相同的方式处理。

答案 1 :(得分:8)

这是封装异步操作并将其参数和上下文保存在一个地方的好方法。

E.g。 HTTP请求:您通过套接字发送请求,并等待响应到达。如果您的申请是在Web浏览器中,您不希望在请求完成之前阻止,而是继续。如果响应到了,您必须在上下文中继续,例如读取数据并将其放入正确的位置(例如,将下载的图像数据放在某处以便以后渲染)。如果您有一个大型客户端类触发多个异步操作,那么将响应与其所属的上下文相匹配可能会变得棘手。回复可能以任意顺序到达。哪个回复属于什么?响应又应该怎么办?如何处理可能的错误?如果您将这些请求封装在命令中并让命令只接收自己的响应,那么他们将更好地了解如何从那里继续并处理响应。如果您有一系列请求/响应,那么跟踪序列的状态也会容易得多。可以将命令分组到复合命令(复合模式)。 客户端传递命令所需的所有内容,并等待命令完成,报告成功或错误。

使用多线程时的另一大优势是:如果操作所需的所有数据都封装在命令对象中,则很容易将命令移动到另一个线程并在那里执行,在线程之间共享对象时遇到的常见锁定问题。创建命令,传递它所需的一切(复制,而不是通过引用),传递给其他线程,仅在接收结果时完成同步。

答案 2 :(得分:6)

命令模式将知道如何进行某些工作的代码与知道何时需要完成的代码以及使用什么参数进行分离。

最明显的情况是一个按钮,它知道你何时点击它,但不知道那时要做什么工作。命令模式允许您将do-some-work对象传递给按钮,该按钮在单击时调用该对象。

答案 3 :(得分:1)

基本上,Command模式是在Java(或C#)中部分实现“作为对象的功能”的一种方式。

因为你不能只是创建一个函数(或方法)并随心所欲地做任何事情,比如把它作为参数传递给其他函数或者将它保存在变量中以便以后执行,这就是解决这个问题的方法。 :

  1. 您将一些代码包装在一个类中(这是您的execute方法)。
  2. 实例化该课程。现在,您拥有的这个对象是“作为对象的功能”。
  3. 您可以将对象作为参数传递,保留它或其他任何内容。
  4. 最后,您需要调用execute方法。

答案 4 :(得分:0)

它描述了一个问题的解决方案。主要是,我们想要发出命令,并且不希望在8个类中定义30个方法来实现这一点。通过使用模式提及,我们发出一个Command对象,该对象可以自由地忽略它,或者以某种方式对其进行操作。 Command对象的复杂性是实现定义的,但这是告诉对象“嘿,做这个”的好方法。

另外,因为我们已经将它封装在一个对象中,我们可以进一步排队命令,按照我们希望的间隔调度它们并将它们还原(当然,提供命令的对象可以'撤消'命令以及'做它')。

因此,想象一下允许您向画布添加形状的绘图包。每次用户执行此操作时,都可以发出命令:

m_Canvas.push_back(new Line(1.0f, 2.0f));
m_Canvas.push_back(new Line(3.5f, 3.1f));
m_Canvas.push_back(new Circle(2.0f, 3.0f, 1.5f));

等等。假设LineCircle来自公共Command基类。

我们的渲染器可以使用此画布集合作为渲染方式,而取消操作只是删除上次执行的命令的情况。通过跟踪用户在单独的集合中执行的操作,我们还可以重做。