【问题标题】:What is the exact definition of the strategy design pattern?策略设计模式的确切定义是什么?
【发布时间】:2010-10-15 17:02:00
【问题描述】:

我与某人就战略模式的真正含义发生了一场极客之争,我需要一位专家来解决这个问题。

我们都同意策略模式允许在运行时交换类的内容(例如行为),同时保持相同的接口。然而,她的论点是“为了使 [算法] 成为一种策略,你必须得到相同的结果”。我的论点是,交换“算法”或类的逻辑可能意味着覆盖操作的结果不同,但它仍然符合策略模式的目的、意图(和分类)。

她的 cmets 代码示例:


根据您的定义,一个类的任何子类都是一种策略。它们具有相同的方法定义(签名),因此可以互换。

Interface Strategy
{
    DoArithmatic(int[] a)
}

Class A : Strategy
public int DoArithmatic(int[]a)
{
     int temp = 0;
     for(int i =0; i< a.length; i++)
          temp += a[i]
}

Class B : Strategy
public int DoArithmaticB(int[]a)
{
     int temp = 0;
     for(int i =a.length -1; i>-1; i--)
          temp += a[i]
}

Class C : Strategy
public int DoArithmatic(int[]a)
{
     int temp = 0;
     for(int i =0; i< a.length; i++)
          temp -= a;
}

int[] a = { 1,2,3 }
ClassA.DoArithmatic(a) = 6
ClassB.DoArithmatic(a) = 6
ClassC.DoArithmatic(a) = -6//This one is not interchangeable

前两个是策略。因为对于任何输入,他们都会给你完全相同的答案。最后一个不是。仅仅因为它给你一个 int 并不能使它成为一种策略。他们必须“做”同样的事情。

您不能仅仅为了使它们成为一种策略而使用“更高”的抽象术语。

这些都在做“数学”,但并不是都以不同的方式做“相同”的事情。这就是战略的精髓。

那么,谁是对的?

【问题讨论】:

    标签: oop design-patterns strategy-pattern


    【解决方案1】:

    先生您是对的,您的同事需要阅读 GoF。

    “策略模式让算法独立于使用它们的客户端而变化。”

    见:

    http://www.dofactory.com/Patterns/PatternStrategy.aspx

    【讨论】:

    • 它让算法变化,但它让它们的结果变化吗?即:它让实现有所不同,但是接口呢?这就是问题所在。
    • ??该问题特别指出“我们都同意策略模式允许在运行时交换类的内容(例如行为),同时保持相同的接口”
    • “独立于客户而变化”好的,但是它们之间如何变化(战略与战略)?就是这个问题。
    • bob:接口我的意思是契约,即行为
    • eljenso:它们各不相同,因为它们可以输出不同的结果
    【解决方案2】:

    从技术上讲,策略可以为所欲为。

    只有当“外部环境”规定了一些无法在程序界面中捕获的固定且可重复的行为(称它们为“理想的属性”)时,您才需要注意您的策略是真正可替代的 à la Liskov关于这些理想的属性。

    【讨论】:

      【解决方案3】:

      我支持你的意见。只要可以在相同的上下文中使用不同的策略,它们就可以做非常不同的事情。

      例如,如果您想访问树中的每个节点,有效的策略可能是:

      • 深度优先搜索预订
      • DFS 后订单
      • BFS
      • 随机的
      • ...

      所有策略都会以不同的顺序访问节点,但目标(访问每个节点)是相同的。因此,如果顺序无关紧要,任何一种策略都适合您的需求。

      【讨论】:

        【解决方案4】:

        FWIW,Wikipedia article 同意你的观点,从未听说过她的职位。

        【讨论】:

          【解决方案5】:

          前两个是策略。因为对于任何输入,他们都会给你完全相同的答案。最后一个不是。仅仅因为它给你一个 int 并不能使它成为一种策略。他们必须“做”同样的事情。

          他们必须做同样的事情,但这并不意味着他们给出完全相同的结果。来自 GoF 的激励示例是不同的布局算法或不同的寄存器分配算法之一。这些策略具有相同的目标——在页面上布局文本和图像块,或将虚拟寄存器分配给硬件寄存器——但它们不必创建完全相同的结果。

          因此,如果您的示例中Strategy 的目标是对输入进行任何算术运算,那么每个示例都是实现该目标的策略。如果目标是对传递的数组求和,DoArithmatic 将被称为CalculateSum,最后一个示例将不符合策略的约定,因此违反了LSP

          【讨论】:

            【解决方案6】:

            根据“Head first Design Patterns” (see here) page 24

            “策略模式定义了一系列算法,
            封装每一个,并使它们可以互换。
            策略让算法独立于
            使用它的客户。 "

            所以先生你是对的,至少根据定义模式的人来说,但他们知道什么。

            【讨论】:

              【解决方案7】:

              你是。该策略的重点是替换算法。它们是否提供相同的结果是所需行为的副产品。

              【讨论】:

                【解决方案8】:

                我认为更正确的说法是策略是否必须在确定性上相同的问题超出了策略模式定义的范围。

                如果一个函数对于给定的输入总是返回相同的结果,它是确定性的。如果两个函数是确定性的,并且它们总是为相同的输入返回相同的值,那么它们在确定性上是等价的。它们可能有也可能没有相同的副作用;如果他们这样做了,那么他们就是完全等价的。

                通常情况并非如此。让我们考虑一个似乎需要确定性等价的例子:排序。您可能会认为,如果两个比较器实现未能为相同的输入返回相同的结果,那么其中至少一个肯定是错误的,但情况不一定如此。

                排序顺序因国家/地区而异。有些地方对重音不敏感。有些人把 McDuck 和 MacDuck 放在一起,等等。这些是策略,这是策略模式的完美应用,而且这些策略肯定不是确定性等价的。

                你赢了。

                【讨论】:

                  【解决方案9】:

                  我也必须同意。一个很好的例子是定价计算器策略。您可以有不同的策略来计算发票的最终金额,具体取决于项目数量、客户类型、运输目的地等几个变量。这些策略中的每一个肯定会返回不同的结果,并且仍然会被考虑策略模式。

                  【讨论】:

                    猜你喜欢
                    • 2010-12-12
                    • 2015-06-18
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-03-31
                    • 1970-01-01
                    • 2012-10-20
                    • 1970-01-01
                    相关资源
                    最近更新 更多