Внедрение в конструктор - можно ли использовать новый нулевой объект, если в конструкторе нет ничего? - PullRequest
6 голосов
/ 30 ноября 2011

Представьте, что у меня есть несколько классов, которые могут вести журналы, поэтому я создал интерфейс регистратора и несколько реализаций (запись в файл, в стандартный вывод, в базу данных и т. Д.), Но иногда я этого не делаю Забота о регистрации этих сообщений, поэтому я сделал реализацию, которая просто игнорирует все сообщения.

Теперь это помогает избежать if s и просто использовать $this->logger->write($message), но мне все равно приходится вводить фиктивный логгер каждый раз.

Так будет ли вред делать такие вещи, как: $this->logger = $logger ? $logger : new DummyLogger() в конструкторе.

Обычно я не работаю в конструкторе, но такие вещи не кажутся слишком опасными.

Вы бы выбрали этот подход?

Ответы [ 2 ]

1 голос
/ 30 ноября 2011

Я бы не выбрал этот подход, потому что это жесткая зависимость и дополнительный класс.Существуют шаблоны, позволяющие избежать этих проблем - и решить вашу дилемму.

Вы можете реализовать версию шаблона наблюдателя, например:

class Loggable
{
    protected $aLoggers = array();

    public function addLogger(Logger $oLog) {
        $this->aLoggers[] = $oLog;
    }

    public function invokeLoggers($sMessage) {
        foreach($this->aLoggers as $oLog) {
            $oLog->write($sMessage);
        }
    }
}

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

class SomeClass extends Loggable
{
    public function doSomething()
    {
        // Some code
        $this->invokeLoggers();
    }
}

$oSomeClass = new SomeClass();
$oSomeClass->addLogger(new FileLogger());
$oSomeClass->addLogger(new DatabaseLogger());
$oSomeClass->addLogger(new EmailLogger());
$oSomeClass->doSomething();
1 голос
/ 30 ноября 2011

Прежде чем ответить на ваш вопрос, я бы предложил переосмыслить вашу архитектуру Logger.Ведение журнала всегда одинаково.Вы пишете сообщение куда-нибудь.Единственное, что отличается, это часть где-то , поэтому имеет смысл разделить ваш Logger на общий Logger и различных Writers.Это обеспечивает большую гибкость, например, вы можете использовать шаблон Composite для одновременной записи в несколько регистраторов.

Относительно вашего вопроса: в общем, вы хотите избежать жесткого кодирования зависимостей в коде, потому что это напрямую повлияет натестируемость и возможность повторного использования, например, ваш регистратор может быть использован только с этим конкретным NullWriter.Если вы собираетесь распространять Logger, вам также придется распространять Writer.

Тем не менее, при условии, что вы все равно будете распространять Logger вместе со всем пакетом Writers, и вы также предоставите средства длявпрыск ctor, я не вижу большой проблемы.Вы все равно можете поменять Writer, если это необходимо, так что все хорошо.

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

Альтернативой назначению NullWriter изнутри Logger будет использование LoggerFactory, которая создает Logger.и указанный Writer вводит Writer и возвращает Logger.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...