2010-02-11 58 views
2

處理多個類業務,我有以下工廠方法:在工廠

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錯誤,類調用
功能。

問題是,在函數運行後,類設置完成後,我無法訪問ErrorHandler類,這意味着我無法關閉它/更改屬性/訪問方法等。

我不知道是否是最好的方法做到這一點是提供了一個公共的訪問方法搶的ErrorHandler,是這樣的:

public function buildErrorHandler() 
{ 
    if($this->handler == null) 
    { 
     $this->handler = new ErrorHandler(); 
    } 

    return $this->handler; 
} 

這種方法將允許工廠創建一個新的實例的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功能(發生錯誤時調用函數),那麼我可以更容易地重用它們兩者。

+0

此資源幫助我http://anvilstudios.co.za/blog/2010/05/03/error-vs-exception-part-1/ – Isius 2014-02-11 20:50:10

回答

0

您可以更改createErrorNotifier()以返回包含給定實例的處理程序和通知程序的標準對象。那麼你不需要擔心吸氣劑,並與新的通知器混合使用。例如,請嘗試以下變化:

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); 

我希望這有助於!

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中() )。