Использую ли я шаблон «Стратегия» или «Команда» для своего случая?

У меня есть два алгоритма, которые я реализую:

  • Алгоритм A, который работает со значениями Vector и
  • АлгоритмB, работающий со значениями Matrix

Что общего у алгоритмов:

  • Оба являются алгоритмами «суммирования», которые снабжены одной и той же последовательностью входных данных. Алгоритмы немного различаются в зависимости от того, следует ли учитывать конкретное значение или нет. Они также различаются по вычислениям, которые должны выполняться для каждого значения последовательности.
  • На оба алгоритма ссылается один и тот же объект (например, «Antenna», который использует алгоритм для передачи или получения).
  • В обоих случаях я хочу иметь возможность сериализовать результат вектора или матрицы. Кроме того, я должен иметь возможность инициализировать любой из алгоритмов (десериализованными) значениями вектора/матрицы, вычисленными из более раннего поколения.

Сначала я попытался реализовать описанное выше с помощью шаблона «Стратегия», но вскоре понял, что шаблон стратегии может быть не самым лучшим из-за различных типов/значений. И чтобы еще больше усложнить ситуацию, мой объект 'Antenna' может использовать любой из алгоритмов в любом направлении:

class Antenna
{
    private AlgorithmParams _algorithm;
}

class AlgorithmParams
{
     private IAlgorithm _transmit;
     private IAlgorithm _receive;
}   

который, как мне кажется, многократно дублирует понятие «передача» и «получение» (поскольку AlgorithmA, который реализует IAlgorithm, сам имеет производные типы «AlgorithmATransmit» и «AlgorithmAReceive», т.е. небольшие вариации в пределах одного и того же алгоритма в зависимости от направления).

Я также хотел бы иметь более четкое разделение между логикой алгоритма и сериализованными данными.

Буду рад услышать ваши мнения по этому поводу. Спасибо !


person alhazen    schedule 24.05.2012    source источник


Ответы (1)


Для меня шаблон стратегии — это не что иное, как просто использование композиции объектов, позволяющее использовать множество различных стратегий в классе И обмениваться ими во время выполнения. В вашем случае вы МОЖЕТЕ использовать шаблон стратегии, если хотите, чтобы класс антенны менял свое поведение (алгоритм) во время выполнения на основе входных значений. Если это так, то в классе Antenna у вас есть переменная экземпляра, указывающая на AlgorithmInterface, производный от 4 классов: AlgoATransmit, AlgoBTransmit, AlgoAReceive и AlgoBReceive. Каждый из этих 4 классов будет определять настоящие алгоритмы. Затем вам нужен клиентский класс, который проверяет типы входных значений, и настройте антенну на использование соответствующего алгоритма.

Хотя я не понимаю, как можно применить шаблон команды, ваша проблема также может быть хорошим примером шаблона метода шаблона, и вы можете использовать его в дополнение к стратегии. Что вы можете сделать, так это иметь абстрактный класс, назовем его AbstractAlgorithm, который имеет «метод шаблона», который определяет общий поток алгоритмов, вызывая отдельные функции. Эти функции будут переопределены в подклассах, например. Алгоритм А, Алгоритм Б.

Направление антенны можно определить с помощью «крючков» внутри метода шаблона. Хуки — это в основном функции, которые необязательно переопределять в подклассах.

Вот простой пример кода. Антенна использует композицию объектов и стратегию, имеет переменную, указывающую на абстрактный алгоритм, полученный из двух алгоритмов. Таким образом, схема алгоритмов может быть указана в одном месте, а каждый конкретный шаг определен в подклассах. Надеюсь, это поможет, и я надеюсь, что правильно понял вашу проблему.

class Antenna {
    private AbstractAlgorithm algo;
    void SetAlgo(AbstractAlgorithm newAlgo) {
        algo = newAlgo;
    }
}

class AbstractAlgorithm {

    //this is the template method
    void runAlgo() {   
          step1();        //step1 and step2 are two common steps for both algorithms
          step2();
          if (isMatrixValue())
             step3();            //a hook, only AlgoB will override it.
          if (isTransmitting())
             step4();            //a hook, use for transmit
          else if (isReceiving())
             step5();            //a hook, use for receive

    }

    abstract void step1();
    abstract void step2();
    boolean isMatrixValue() {
         return false;         //default value, to not run step3
    }

}

class AlgorithmA {

    void step1() {
         //some implementation
    }
    void step2() {
         //some implementation
    }

    //use the default false value for isMatrixValue(), not to run step3


}


class AlgorithmB {

    void step1() {
         //some implementation
    }
    void step2() {
         //some implementation
    }
    void step3() {
         //some implementation
    }
    boolean isMatrixValue() {
         return true;         //return true and override step3
    }

}
person Son Do Lenh    schedule 24.05.2012
comment
Большое спасибо за ответ ! Если я не ошибаюсь, не ограничит ли ваше предложение антенну реализацией одного и того же типа алгоритма как для передачи, так и для приема? В моей модели антенна может иметь алгоритм A для передачи и алгоритм B для приема. Спасибо. - person alhazen; 25.05.2012
comment
привет Альхазен, как вы выбираете между передачей и получением? и как они влияют на алгоритмы? есть ли разница в AlgoA или AlgoB, когда он реализует любое направление? - person Son Do Lenh; 27.05.2012