处理工厂中的多个类操作

时间:2010-02-11 05:14:26

标签: php oop

我有以下工厂方法:

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类,这意味着我无法关闭它/更改属性/访问方法等。< / p>

我想知道执行此操作的最佳方法是提供一个公共访问器方法来获取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等)。

你会如何处理这样的事情?我完全不反对改变班级的设计。

我非常担心只是合并这两个类,因为它基本上会使整个事情“不可重用”。如果我从errorNotifier功能(处理错误)中分离errorHandler功能(在发生错误时调用函数),那么我可以更容易地重用它们。

2 个答案:

答案 0 :(得分:2)

你可能最好拥有一个代理类或单例,它可以让你在需要时获得错误处理程序。类似的东西:

class ErrorHandler {
    private static $_instance = null;
    public static function getInstance()
    {
         if (null !== self::$_instance) {
              self::$_instance = new ErrorHandler;
         }
         return self::$_instance;
    }

    public static function setInstance(ErrorHandler $instance)
    {
         $oldInstance = self::$_instance;
         self::$_instance = $instance;
         return $oldInstance;
    }
}

这将允许您始终收集ErrorHandler的单个实例(通过ErrorHandler :: getInstance()),并且还可以在需要时全局更改活动实例(通过ErrorHandler :: setInstance())。

答案 1 :(得分:0)

您可以更改createErrorNotifier()以返回包含给定实例的处理程序和通知程序的标准对象。然后你不需要担心getter并将处理程序与更新的通知程序混在一起。例如,尝试以下更改:

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 (object)array(
        'notifier' => $errorNotifier,
        'handler' => $errorHandler,
    );

}

然后,当您调用createErrorNotifier时,您可以访问给定实例的处理程序和通知程序:

$not1 = $obj->createErrorNotifier(...);
var_dump($not1->notifier, $not1->handler);

我希望这有帮助!