命令模式 – 目的?

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

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

我们的想法是,如果将命令封装为对象,则可以捕获,存储,排队,重放等命令。

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

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

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

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

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

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

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

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

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

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

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

另外,因为我们已经将它封装在一个对象中,所以我们可以进一步排队命令,按照我们希望的间隔调度它们并恢复它们(前提是,你发送命令的对象可以’撤消’一个命令以及’做它’)。

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

 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基类派生的。

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