Почему кто-то предпочел бы стратегию stati c динамической c? - PullRequest
2 голосов
/ 24 апреля 2020
#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();
}

Вот пример шаблона стратегии stati c и динамического c, написанного на c ++. Интересно, почему кто-то использует стратегию stati c вместо динамической c. Кажется, что Dynami c один выполняет всю работу с Stati c One, но также обладает большей гибкостью, поскольку стратегия может быть изменена во время выполнения. Кто-нибудь может привести пример, когда стратегия stati c будет лучше, чем стратегия Dynami c?

1 Ответ

2 голосов
/ 24 апреля 2020

Версия stati c является строго более мощной и более простой в использовании.

Версия stati c требует только, чтобы S имела функцию-член execute, тогда как динамическая c версия налагает на пользователя наследование от Strategy.

Версия stati c не предъявляет никаких требований к стратегии выделения или времени жизни, тогда как в фрагменте версия Dynami c требует выделения кучи. Альтернатива версии Dynami c возможна без выделения, если она не становится владельцем, и в этом случае клиент должен быть обеспокоен временем жизни Strategy.

Учитывая версию STATI c, a клиент, который хочет выделить кучу, может стереть тип стратегии, чтобы иметь выделение кучи с одним типом стратегии. Но, учитывая приведенную выше версию dynamici c, клиент не может отменить требование выделения кучи.

Версия stati c полностью видна компилятору, и эта информация доступна для оптимизации. Версия Dynami c косвенно обращается к базовому классу Strategy, поэтому встраивание невозможно, если компилятор не сможет доказать (или предположить) конкретный класс Strategy, который используется.

...