首页 > 解决方案 > 为什么有人更喜欢静态策略而不是动态策略?

问题描述

#include <iostream>

class Strategy
{
public:
    virtual void execute() = 0;
};

class Strategy1 : public Strategy
{
public:

    virtual void execute() override { std::cout << "executed1\n"; }
};

class Strategy2 : public Strategy
{
public:

    virtual void execute() override { std::cout << "executed2\n"; }
};

template <typename S>
class StaticStrategy
{
    S strategy;

public:

    void execute()
    {
        strategy.execute();
    }
};

class DynamicStrategy
{
    Strategy* strategy;

public:

    DynamicStrategy(Strategy* strategy) : strategy(strategy) {}

    void execute()
    {
        strategy->execute();
    }

    void setStrategy(Strategy* newStrategy)
    {
        delete strategy;
        strategy = newStrategy;
    }

    ~DynamicStrategy()
    {
        delete strategy;
    }
};

int main()
{
    StaticStrategy<Strategy1> staticStrategy;
    staticStrategy.execute();

    DynamicStrategy dynamicStrategy(new Strategy1{});
    dynamicStrategy.execute();

    dynamicStrategy.setStrategy(new Strategy2{});
    dynamicStrategy.execute();
}

这是用 C++ 编写的静态和动态策略模式的示例。我想知道为什么有人会使用静态策略而不是动态策略。动态的似乎完成了静态的所有工作,但也具有更大的灵活性,因为可以在运行时更改策略。谁能给我一个静态策略比动态策略更好的例子吗?

标签: c++design-patternsstrategy-pattern

解决方案


The static version is strictly more powerful and easier to use in some ways.

The static version only requires that S have a member function execute, whereas the dynamic version imposes upon the user inheritance from Strategy.

The static version places no requirements on allocation strategy or lifetime, whereas in the snippet the dynamic version requires heap allocation. An alternative of the dynamic version is possible without allocation if it does not take ownership, in which case the client must be concerned with the Strategy lifetime.

Given the static version, a client who wants heap allocation can erase the strategy type to have heap allocation with a single strategy type. But given the dynamic version above, a client cannot undo the requirement for heap allocation.

The static version is completely visible to the compiler and this information is available for optimization. The dynamic version indirects through the Strategy base class, so inlining cannot occur unless the compiler can prove (or speculate) the concrete Strategy class being used.


推荐阅读