nepster-web
@nepster-web

Паттерн «стратегия» на примере определения победителя из списка пользователей

Ранее у меня возникла проблема, ее я описал в вопросе Сравнение пользователей и просчет рейтинга

Мне посоветовали покопать в сторону паттерна "стратегия". Ранее я не работал с данным патерном, поэтому возникли вопросы по организации.

Прочитал несколько материалов про данный паттерн и вот возникли вопросы.

У меня есть массив:

[users] => Array
        (
            [0] => Array
                (
                    [hash] => de2983f989ccf1ea09d1e29a0465fb51
                    [earn] => 32
                )

            [1] => Array
                (
                    [hash] => ef21eb9ea4b5dc9f359024198bf40742
                    [earn] => 23
                )

            [2] => Array
                (
                    [hash] => fff294012895b487157efd570232f0fc
                    [earn] => 22
                )

            [3] => Array
                (
                    [hash] => 3bf51dd7bb302ccf81e335879b97bc5b
                    [earn] => 12
                )

        )


Это список пользователей отсортированный по достижениям (по набранным очкам). Мне нужно определить победителя и записать логи (Кто выиграл, кто проиграл, накинуть рейтинг и тп).

В одном из примеров реализации стратегии я видел как реализовывают валидатор форм, тоесть создают методы, которые проверяют данные и в одном файле просто прогоняют все это дело по циклу тем самым избавляюсь от большой конструкции if else.

В данной ситуации у меня есть несколько вариантов, которые нужно проработать:
- определить победителя (тот кто набрал больше всех очков)
- если стоит специальный флаг, то победитель будет 1 и 2 место
- если вдруг 1 и 2 место набрали одинаковое кол-во очков
- если вдруг стоит специальный флаг и 2 и 3 место набрали одинаковое кол-во очков
- если все пользователи набрали одинаковое кол-во очков

Вот эти все моменты мне нужно обработать следующим образом:
- если есть победитель, дать ему рейтинг накинуть счетчик игр и тп.
- если стоит специальный флаг, то победитель будет 1 и 2 место. Накинуть 1 место 70% рейтинга, 2 место 30%, и тп.

Итак, когда я начинал это делать без паттерна, вырос большой жирный код с множеством проверок.

Итак сел продумывать как бы это все реализовать паттерном. Так как ранее не работал со стратегией, хочу понять как будет на моем примере возможность реализации.

Как я понял первым делом нам нужен абстрактный класс, от которого будут наследоваться все остальные.
далее я реализую класс с методами всех возможных вариантов. То есть методы:
- победитель 1 место
- победитель 1 и 2 место
- ничья 1 и 2 место
- ничья 2 и 3 место
- ничья у всех

А вот как дальше? То есть как будет выглядеть первый файл из которого мы все это дело будем инициализировать? Подскажите пожалуйста как лучше начать?
  • Вопрос задан
  • 3141 просмотр
Пригласить эксперта
Ответы на вопрос 2
redc0de
@redc0de
В паттерне стратегия для класса задается какое-то поведение, у каждого поведения есть свой алгоритм, для начала нужно посмотреть на простом примере вообще какие классы и интерфейсы там есть, но суть в том что у вас будет один класс Участник и будет 5 Классов поведения.

IBehavior
- public function calculate($data);


WinnerFirstBehavior implements IBehavior
WinnerFirstSecondBehavior ... 
DrawFirstSecondBehavior ... 
DrawSecondThirdBehavior ...
DrawAllBehavior ...


class Player
{
    private $behavior;
    private $score;

    public function __construct(IBehavior $behavior, $score)
    {
        $this->behavior = $behavior;
        $this->score = $score;
    }

    public function calculate()
    {
        return $this->behavior->calculate($this->score);
    }
}
Ответ написан
@M_PRO
Здесь как раз не тот случай, когда не применим этот патерн. Точнее если его использовать, то придётся писать всего две "стратегии" (со специальным флагом и без). Но классов всё равно получится 3-4. Такова уж плата за использование патернов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы