Как архитектурно лучше решить такую проблему?

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

В проекте, очень часто нужно писать в файловых лог, и каждый раз создавать объект заново и конфигурировать его - не хорошо.

Например:

use Monolog\Handler\StreamHandler;
use Monolog\Logger;

$logger = new Logger('my_logger');

$logger->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::WARNING));
$logger->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::DEBUG, $bubble = true));

$logger->pushProcessor(function ($record) {
    $record['extra']['cookies'] = $_COOKIE;
    return $record;
});

как минимум - это дублирование кода + неудобно.

Значит нужно вынести создание объекта а отдельный метод. Но куда ? Если создать метод в самом логгере - это не его зона ответственности, завтра, может унжен будет еще один метод, для логирования в rabbitmq.

Как быть ? Создать отдельный класс-фабрику ? Но разве идея фабрики не в том, что она может создавать объекты одного интерфейса ? а тут у нас фабрика все время возвращает один и тот же объект, только в разных конфигурациях ?

Какие вообще есть решения ?


Ответы (1 шт):

Автор решения: Alex Khonko

используйте dependency injection


// 1 делаем наш логгер синглтоном
// в каждом фреймворке это делается по-своему(ну или реально паттерном)

// пример yii
// common/config/main.php
'singletons' => [
    LoggerInterface::class => [
         'class' => YourLoggerClass::class
         'param1' => 'val1',
         'param2' => 'val2',
         // ......
     ],
],




// 2 протягиваем его в класс через DI механизм фремворка

// 2.1 через конструктор(более классический вариант)

public function __construct(LoggerInterface $logger){
    $this->logger = $logger;
}

// 2.2 через контейнер(в каждом фрейме по своему)
public function doSth()
{
    /** @var LoggerInterface $logger */
    $logger = Yii::$container->get(LoggerInterface::class);
    // код .....
    // код .....
    // код .....
}




→ Ссылка