nepster-web
@nepster-web

Связанность модулей, как лучше всего организовать конфигурацию ?

Итак собственно копал на тему низкой связанности и писал структуру, которая требует тесного взаимодействия.

Собственно пишу игру, в которой есть элементы сетевого маркетинга.

Предположим несколько модулей:
- Бинарий
- Ранги
- Бонус
- БухУчет
...

Я столкнулся с таким моментом, что мне нужно взаимодействовать всеми модулями с модулем БухУчета.
Тоесть:
- Бинарий, пользователь получает баллы и обменивает их (фиксируем в бух учете)
- Ранги, пользователь достигает ранга и получает премиальные (фиксируем в бух учете)
- Бонус, пользователь получает бонусы (фиксируем в бух учете)
...

Когда я разрабатывал первую версию, я скажем так особо не парился ну и делал в каждом модуле вызов БухУчета и наоборот (Когда идет таблица бух учета и он должен знать, кому какая запись принадлежит).
Простыми словами, каждый модуль четко знал о друг друге.

Как мне объяснили это не правильно. И с пришел к следующему решению:

В модуле БухУчет, о всех остальных модулях знает только конфигурация. В этом файле конфигурации есть вот такой метод:

/**
     * Merchant типы с зависимых модулей
     * @return $array
     */
    public function getTypes() {

        $parentDependencesArray = parent::getTypes();

        $dependences = [
            'business\modules\users\activate\components\CommonProcess::getTypeArray',
            'business\modules\users\activate\components\MarketingLine::getTypeArray',
            'business\modules\users\activate\components\MarketingBinary::getTypeArray',
            'business\modules\users\activate\components\Rangs::getTypeArray',
            'business\modules\users\activate\components\LeaderBonus::getTypeArray',
        ];
        
        $array = [];
        
        foreach($dependences as $dependence) {
            $array = array_merge($array, call_user_func($dependence));
        }
        
        return array_merge($array, $parentDependencesArray);
    }


Тоесть он получает массив статусов всех зависимых модулей. Итак БухУчет знаком со всеми зависимыми модулями только строкой, которая подключает файл (конечно можно отдельно еще вынести сам массив модулей но это такое).

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

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

Опять у нас есть файл конфигурации:

// Дополнительные компоненты
    'components' => [
    
            // Основные процессы
            [
                'class' => '\business\modules\users\activate\components\CommonProcess',
                'income'       => 0,
                'profit'       => 13,
                'shareholders' => 30,
            ],
            
            // Линейный Маркетинг
            [
                'class' => '\business\modules\users\activate\components\MarketingLine',
                'allocationProfit' => [10,3,3,3,3,3,3,3,3,3], // Распределение прибыли по линиям
                'income'       => 37,
                'profit'       => 0,
                'shareholders' => 0,
            ],
            
            
            // Бинарный Маркетинг
            [
                'class' => '\business\modules\users\activate\components\MarketingBinary',
                'income'       => 75,
                'profit'       => 0,
                'shareholders' => 0,
                
            ],
            ...
    ],


НУ и в классе активации, штука которая проверяет все ошибки выбрасывая исключения, а если все хорошо, то:
foreach($this->_config['components'] as $key => $config) {
            $refClass = new \ReflectionClass($config['class']);
            $object = $refClass->newInstanceArgs(['user'=>$this->_user, 'sponsors'=>$this->_sponsors, 'config'=>$config, 'common'=>$this->_config['common']]);
        }


Запускает каждый компонент передавая в него все необходимые данные.

Теперь собственно вопрос:
Что касается такого способа конфигурации, будет ли это оптимально и красиво ? Вопрос к бородатым дядькам.
  • Вопрос задан
  • 2391 просмотр
Решения вопроса 2
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Почему бы не воспользоваться нормальным Dependency Injection контейнером и не прописать все зависимости нормально?
Ответ написан
@1Michael1
IoC
что-то о чем-то конкретном вообще не должно знать
по сути получится так, что есть "модуль" который исполняет свою логику. в конструктор передается все то, что должно "инициализировать" модуль (конфиг конкретно для него, все общеиспользуемые зависимости типа кеша, логгера и т. п.)
ну а в конкретном методе будет вызов реализации. есть возможность вынести что-то в абстракцию (судя по всему должно было бы быть) - было бы хорошо объединить это более общим интерфейсом
P.S. это довольно высокоуровневая точка входа
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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