dmitriylanets
@dmitriylanets
веб-разработчик

Как лучше использовать инфраструктурный код?

Имеются классы спроектированные в зависимости от предметной области например EmailServer, MailBox, Mail, Attachment
данные классы наделены соответствующими свойствами/методами согласно задачам бизнес логики. Например получение писем выглядит как $Mails = (new MailServer($host,$login,$password))->getMalBox("INBOX")->getMails();
то есть понятно что Объект сервера содержит каталогов писем, получение писем возможно через каталог INBOX(Входящие) в качестве примера.
Ясно что класс MailServer содержим в конструкторе явно то что нужно данной модели.
Возникает ситуация внедрить код который не относится к проектируемой предметной области и относится скорее к инфраструктурному, например классы Logger, для логирования чего либо, Config который может содержать настройки проекта, Profiler который собирает информацию о работе приложения и тп.
Вижу варианты:
1. Засорять конструкторы данными зависимостями инфраструктурного кода
2. Внедрять зависимости через Контейнер, но опять же все классы должны иметь данную зависимость
3. Использовать синглтон Контейнер $Logger = Continer::get_instance()->get("Logger");
4. Использовать класс фасад который будет работать с моделями и инфраструктурным кодом, что то вроде MailService
  • Вопрос задан
  • 169 просмотров
Пригласить эксперта
Ответы на вопрос 1
@smple
Указанные тобой варианты имеют право на существование, также я бы дополнил список
5. использовать Proxy объект
6. Использовать di и на основе настроект di подсовывать реализацию и параметры из конфигов

Например у твоего MailServer есть interface MailServerInterface от который будет использоваться тобой везде, у тебя есть эталонная реализация MailServer и тебе надо сделать логирование методов.
```php
MailServerProxy implements MailServerInterface {
public function __construct (LoggerInterface $logger, MailServerInterface $server) {
$this->setLogger($logger);
$this->setMailServer($server);
}
public function __call($name, $args) {
$this->logger->info('called method ' . $name);
return call_user_func_array([$this->mailServer, $name], $args);
}
}
```
Примерный шаблон кода.

Тогда там где нужен MailServerInterface его будет создавать di, а уже di в зависимости от настроек системы будет создавать зависимости, например если надо логировать, то будет создавать MailServerProxy которому аргументами нужен Logger(тут любые параметры могут быть) и MailServer (а ему нужны аргументы $host, $login, $password которые в конфиге лежат и их читать будет di)

А в случае если логирование не нужно станет, достаточно в настройках di при запросе MailServerInterface создавать MailServer сразу, ну или использовать NullLogger какой нибудь который ничего не пишет.

также есть еще аспектно ориентированное программирование https://github.com/goaop/framework
но оно работает медленнее так как надо прочитать анотации через reflection но тоже может быть не плохо.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы