У меня есть следующий фабричный метод:
public function createErrorNotifier($verbose_output = false, $logging = false)
{
// First we get the handler
$errorHandler = $this->buildErrorHandler();
$errorNotifier = $this->buildErrorNotifier();
// We attach the notifier to the handler
$errorHandler->setCallback(array($errorNotifier, "throwException"));
// Return the Notifier
return $errorNotifier;
}
protected function buildErrorHandler()
{
return new ErrorHandler(error_reporting());
}
protected function buildErrorNotifier()
{
return new ErrorNotifier();
}
По сути, $errorHandler
- это класс, который при обнаружении ошибки PHP вызывает
$errorNotifier->throwException()
функция.
Проблема в том, что после запуска функции и настройки класса у меня нет доступа к классу ErrorHandler, что означает, что я не могу его отключить / изменить свойства / методы доступа и т. Д.
Мне интересно, лучший ли способ сделать это - предоставить открытый метод доступа для захвата errorHandler, что-то вроде:
public function buildErrorHandler()
{
if($this->handler == null)
{
$this->handler = new ErrorHandler();
}
return $this->handler;
}
Этот метод позволит Factory создавать новый экземпляр ErrorHandler и позволит внешнему коду получить доступ к ErrorHandler. Но затем я сталкиваюсь с проблемой, что если я хочу пойти и создать другой ErrorNotifier, первый перестанет работать, так как я переназначаю функцию обратного вызова для нового объекта. Похоже, что это будет крайне плохая практика, так как это будет неожиданное поведение.
У меня такое ощущение, что установка какого-либо "глобального" errorHandler заставила бы меня отключиться из-за этой же проблемы, так как во второй раз, когда я вызываю createErrorNotifier, первый не будет вызываться больше.
Может быть, решение может заключаться в том, чтобы вместо этого дать ErrorNotifier экземпляр ErrorHandler, и тогда ErrorNotifier может выступать в качестве прокси между клиентом и ErrorHandler? Что-то вроде:
class ErrorNotifier{
public function __construct(ErrorHandler $handler)
{
$this->errorHandler = $handler;
$this->setCallback(array($this, "throwException"));
}
public function setCallback($callback)
{
$this->errorHandler->setCallback($callback);
}
}
Другой вариант может заключаться в том, чтобы полностью забыть об ErrorHandler и положиться на клиента, чтобы связать ErrorNotifier с каким-либо обработчиком (set_exception_handler()
, ErrorhHandler и т. Д.).
Как бы вы справились с чем-то вроде этого? Я вовсе не против изменения дизайна классов.
Я очень настороженно отношусь к простому объединению двух классов, так как это фактически делает все это «не пригодным для повторного использования». Если я отделю функциональность errorHandler (вызывая функцию при возникновении ошибки) от функциональности errorNotifier (имея дело с ошибкой), тогда я смогу намного проще использовать их оба.