战略模式与继承的差异

Rez*_*imi 11 c++ inheritance design-patterns strategy-pattern object-oriented-analysis

有一个相同的概念Strategy PatternInheritance,这样我就可以实现Strategy PatternInheritance这听起来很简单和清晰Strategy Pattern.

Startegy Pattern:

class IBase
{
public:
    virtual void processAction(void *data) = 0; // pure virtual
}

class Worker: public IBase
{
public:
    virtual void processAction(void *data)
    {
        // define logic
    }
}
Run Code Online (Sandbox Code Playgroud)

Inheritance:

class Base
{
public:
    virtual void processAction(void *data) {}
}

class Worker: public Base
{
public:
    virtual void processAction(void *data) override
    {
        // define logic
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是它们之间有什么区别?或什么时候应该使用Strategy PatternInheritance

链接:战略模式

JB *_*zet 20

想象一下,你设计了一个缓存.缓存可以有关于的选项

  • 驱逐政策(LIFO,FIFO,LRU)
  • 到期策略(读后,写后)
  • 最大大小(元素数量,内存使用量)

现在想象一下,您希望让缓存的用户选择这些选项中的任何一个,并使用继承.你需要3*2*2 = 12个不同的类:

  • LifoAfterReadNumberOfElementsBasedCache,
  • LifoAfterReadMemoryBasedCache,
  • 等等

4个LifoXxx类中的每一个都必须实现相同的算法来实现LIFO策略.其他的相同.

使用策略模式而不是继承来实现它,您将拥有一个Cache类和7个策略类(每个策略一个),您可以根据需要进行组合,而无需重复代码.

您还可以让您的缓存用户定义您自己的策略,这是您没有预料到的,并让他将其与其他策略结合起来,而无需创建大量新的子类.

  • `cache.useEvictionStrategy(new LifoStrategy());` (2认同)

Val*_* P. 6

策略是OOP的模式,继承是OOP的原则.策略是使用(或支持)继承(实际上是接口泛化)来实现的.

遗产

  • 继承用于实现OOP的所有好处(它最终导致更好的可读性\可维护性\代码结构).
  • 继承用于形成许多其他模式,而不仅仅是策略
  • 由于其静态编译时性质,继承有时是一种限制

战略

  • 策略假设具有不同的实现,可以在运行时替换(或以灵活的方式配置).所以,你的第一个例子也不是策略.
  • 通常,作为逻辑重用方式的组合(由Strategy实现)优于继承.首先,它提供了动态多态性.第二,它具有较少的实现限制,如多类继承等.
  • 策略对应于DDD方面的"一些可变算法",因此对域建模具有实际影响.
  • 策略作为模式本身,为开发人员之间的通信提供了一种语言("模式语言").

而且,根据你的例子:

  • 基本抽象类和接口有两种不同的语义,因此在您的示例中的继承也具有不同的语义.首先是关于公共合同的实施.其次是关于泛化作为共同属性和方法的提取.


Don*_*oby 5

答案在您在问题中链接的维基百科文章中。

策略模式使用组合而不是继承。在策略模式中,行为被定义为单独的接口和实现这些接口的特定类。这允许在行为和使用该行为的类之间更好地解耦。可以在不破坏使用它的类的情况下更改行为,并且类可以通过更改使用的特定实现来在行为之间切换,而无需任何重大的代码更改。行为也可以在运行时和设计时更改。

如果您的情况是简单和静态的,您当然可以使用继承,但是使用 Strategy 可以让您更好地解耦复杂的代码,并允许在策略的实现之间进行简单的切换,即使在运行时也是如此。

例子可能会有所帮助。这个相关问题的答案以及您的问题的其他答案中都有一些很好的答案。

您希望能够在运行时更改策略的一个非常真实的情况是排序。排序顺序可以因策略(通常称为比较器)而变化,并且您可以有多个策略和机制的实现,供程序用户更改它们。