В паттерне стратегий мы не можем сделать каждую стратегию функцией, а не классом? - PullRequest
9 голосов
/ 08 июня 2009

В обычном паттерне стратегий мы создаем каждую стратегию как класс. Разве мы не можем сделать это функцией и просто присвоить ссылку на функцию, когда создаем экземпляр объекта, и позволить объекту вызвать эту функцию?

Ответы [ 5 ]

4 голосов
/ 08 июня 2009

Зависит от языка. В C # вы можете сделать его делегатом. В Java это был бы анонимный класс. В C ++ вы действительно можете сделать это указателем на функцию.

3 голосов
/ 08 июня 2009

В простейших случаях вы можете заменить шаблоны Стратегии указателем на функцию. Однако рассмотрим этот случай

class HourlyPayStrategy implements PayStrategy
{
    public int calculate()
    {
        int x = doComplexOperation1();
        int y = doComplexOperation2();

        return x + y;
    }

    private int doComplexOperation1()
    {
        // ...
    }

    private int doComplexOperation2()
    {
        // ...
    }
}

Если мы просто дадим простой указатель на функцию, все станет по-настоящему волосатым, потому что вы больше не сможете его реорганизовать (ну, по крайней мере, не полностью инкапсулированным способом).

2 голосов
/ 08 июня 2009

Конечно, хотя, используя объекты, вы можете воспользоваться наследованием так, как вы не могли использовать только функции.

1 голос
/ 08 июня 2009

То, что происходит под капотом в большинстве реализаций C ++, почти то, что вы предлагаете. Компилятор обычно разрешает вызов Strategy.virtualMethod () следующим образом (в псевдокоде):

  (Strategy.pVtable[indexOfVirtualMethod])()

Так что, если ваша единственная забота - это еще одна разыменование указателя (pVtable), вам следует сначала создать профиль, если вы не можете определить более серьезные горячие точки.

Мне кажется, что ваш код будет намного сложнее понять и поддерживать, когда вы используете указатель на функцию вместо объекта стратегии.

1 голос
/ 08 июня 2009

В C # вы можете использовать делегатов с шаблоном стратегии. Взгляните на это сообщение в блоге для примера.

...