'Strategy Design Pattern'不就是多态的基本使用吗?

Is 'Strategy Design Pattern' no more than the basic use of polymorphism?

策略设计模式中,我们做的是

我的问题是,这不就是我们学习的多态和方法重写的基本例子吗?

除了可以使用抽象 class 之外,还可以替换公共接口。

多态性是面向对象编程的三大关键支柱之一:

  • Polymorphism

    In programming languages and type theory, polymorphism [...] is the provision of a single interface to entities of different types.

  • Abstraction

    [A]bstraction is a technique for managing complexity of computer systems. It works by establishing a level of complexity on which a person interacts with the system, suppressing the more complex details below the current level. The programmer works with an idealized interface (usually well defined) and can add additional levels of functionality that would otherwise be too complex to handle.

  • Inheritance

    In object-oriented programming, inheritance is when an object or class is based on another object (prototypal inheritance) or class (class-based inheritance), using the same implementation (inheriting from an object or class) specifying implementation to maintain the same behavior (realizing an interface; inheriting behavior). It is a mechanism for code reuse and to allow independent extensions of the original software via public classes and interfaces.

作为 OOP 的重要支柱,说同样的话就类似于说赛车与驾驶是一回事(驾驶是您正在做的 "core underlying thing")。这也就像说 Facade Pattern 只是抽象。

就像赛车快速且有竞争力一样,Strategy Pattern是多态性在运行时用于select算法的行为。它绝对是多态性的应用和实现,但它确实是多态性的特定应用和实现。

您描述的是一种实现策略模式的方法。您还描述了如何实现大量不同的设计,因为我们可能想要创建一个通用接口、进行不同的实现以及 select 一个在运行时用于不同情况的原因有很多。

还有其他方法可以实现策略模式。

但是,您知道,设计不是代码。设计是软件如何工作的心智模型——人的东西,而不是比特。设计模式是为常见问题编写解决方案的常用方法。它再次发生在你的脑海中,而不是比特。

策略模式特别是关于使用可互换算法制作对象,其中任何一个都可以用于特定目的。

所以,是的,您定义了一个接口...但它不是数据对象的接口 -- 它没有 getter 和 setter 以及状态修改器等。接口定义了对象如何与用于特定目的的算法。国际象棋游戏可能会使用 "Player" 策略,例如,使用名为 "SelectNextMove".

的方法

并且,是的,您实现了该接口,但实现不是 "things" 成为包含对象的 "parts",它们是可用于执行任何功能的不同算法对象需要。国际象棋游戏可以支持许多不同的策略,这些策略可用于 select 计算机玩家的下一步行动。

因此,当您在思考国际象棋游戏的设计时,例如,在您的脑海中,您可能会发现将选择下一步的策略与模拟棋盘的对象分开考虑是很有用的,确保正确记录、传达和呈现 selected 动作。选择下一步的策略与这些无关。

如果你是一个好的软件设计者,你也会独立编写代码,这样代码中的关注点分离就会反映出你头脑中的关注点分离,方便维护代码的人思考它以最有用的方式,并允许选择下一步的新策略随时换入和换出。

多态性:有一个接口或基础 class 可以交换具体实现。

策略模式:逻辑的部分被放入一个单独的class中,由接口访问以交换它。因此,它以特定方式使用多态性。

许多 OO 模式都在使用多态性。他们中的大多数都是基本的。让我们以 composite pattern 为例,我一直认为它最能显示多态性的威力。

Strategy_pattern 使用 运行 时间多态性使算法在该系列中可以互换。

用多种算法替换一种算法是策略模式的一部分。策略模式也可以使用Context。

无需使用interface/run-time多态,即可实现运行次算法替换。

通过传递条件在上下文中调用方法。让 switch case 语句根据个别情况调用不同的方法。这种方法不如 运行 时间多态性那么干净,但您仍然可以实现它。

策略 UML:

相关帖子:

策略实施在 Javascript 等动态语言中甚至可以更简单。每当您传递回调时,您可能正在扩展 Strategy 实现。

示例:排序数组

Javascript 的原生数组有一个名为 sort 的方法,它将 return 一个全新的排序数组。它可以有一个参数,comparisonFunction,一个将比较数组中的 2 项的回调和 return:

  • 1 如果第一个元素被认为高于 第二个。
  • 0如果要算等于
  • -1如果要考虑则更低

因此,您可以使用您想要的任何策略对数组进行排序:

[5, 2, 4, 1, 3].sort(); // default: sort in the natural order

[5, 2, 4, 1, 3].sort(function reverse(first, second){
    if (first > second) return -1;
    if (first == second) return 0;
    if (first < second) return 1;
});

[5, 2, 4, 1, 3].sort(function random(first, second){
    return Math.floor(Math.random() * 3) - 1;
});

当您创建自己的库并期望回调对您的数据做一些工作时,您可能正在实施策略模式。

策略在某些方面可以作为多态的一个例子。但这对于 OOP 新手来说不是一个好的开始,因为它比其他模式更复杂。

是的,您可以用抽象 class 甚至普通 class 替换接口。没关系。 "Abstraction" 在 OOP 中并非所有 classes 都必须是抽象 class 或接口的派生。

我想补充一点,在使用多态性时,您通常必须销毁对象并将其替换为新实例。不断 create/destroy 新实例可能会很昂贵。策略模式是一种实现惰性 loading/storing 先前创建的实例供以后使用的方法。

这里是 Swift 中的示例。

protocol Strategy {

}

class CheapStrategy: Strategy {
    // cheap to create this
}

class ExpensiveStrategy: Strategy {
    // expensive to create this
}

// Polymorphism
// Alternating between different strategies.
// The previous value of s is always created and destroyed.

var s: Strategy!
s = CheapStrategy()
s = ExpensiveStrategy()
s = CheapStrategy()
s = ExpensiveStrategy()


// Strategy Pattern

class Context {
    lazy var cheapStrategy = CheapStrategy()
    lazy var expensiveStrategy = ExpensiveStrategy()
    var s: Strategy!
}

// Alternate between different strategies using previously allocated.

let c = Context()
c.s = c.cheapStrategy
c.s = c.expensiveStrategy
c.s = c.cheapStrategy
c.s = c.expensiveStrategy