2010-02-11 4 views
2

je de la fabrique suivante:opérations de manutention de classe multiple dans une usine

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

Fondamentalement, $errorHandler est une classe qui, lorsqu'il détecte une erreur de PHP, appelle la fonction
. Le problème est qu'après l'exécution de la fonction et la création de la classe, je n'ai pas accès à la classe ErrorHandler, ce qui signifie que je ne peux pas la désactiver/modifier les propriétés/méthodes d'accès, etc.

Je me demande si la meilleure méthode pour le faire serait de prévoir une méthode accesseur public pour saisir le errorHandler, quelque chose comme:

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

    return $this->handler; 
} 

cette méthode permettrait à l'usine de créer une nouvelle instance de ErrorHandler, et permettrait au code externe d'accéder au ErrorHandler. Mais je rencontre ensuite le problème que si je veux aller créer un autre ErrorNotifier, le premier va cesser de fonctionner, car je suis en train de réaffecter le callback au nouvel objet. Cela semble être une pratique extrêmement mauvaise, car ce serait un comportement inattendu. J'ai l'impression que le fait de régler n'importe quel type d'erreur global 'globalHandler me ferait trébucher sur ce même problème, car la deuxième fois que j'appellerai createErrorNotifier, le premier ne sera plus appelé.

Peut-être qu'une solution pourrait être de donner à ErrorNotifier une instance de ErrorHandler, et que ErrorNotifier peut agir comme un proxy entre le client et le ErrorHandler? Quelque chose comme:

class ErrorNotifier{ 
    public function __construct(ErrorHandler $handler) 
    { 
      $this->errorHandler = $handler; 
      $this->setCallback(array($this, "throwException")); 
    } 

    public function setCallback($callback) 
    { 
      $this->errorHandler->setCallback($callback); 
    } 
} 

Une autre option pourrait être d'oublier complètement ErrorHandler, et compter sur le client pour attacher le ErrorNotifier à une sorte de gestionnaire (set_exception_handler(), ErrorhHandler, etc.).

Comment géreriez-vous quelque chose comme ça? Je ne suis pas contre le fait de changer le design des classes.

Je me méfie de la fusion des deux classes, car cela rendrait l'ensemble "non-réutilisable". Si je sépare la fonctionnalité errorHandler (appel d'une fonction lorsqu'une erreur survient) de la fonctionnalité errorNotifier (traitant de l'erreur), je peux alors beaucoup plus facilement les réutiliser tous les deux.

+0

Cette ressource m'a aidé http://anvilstudios.co.za/blog/2010/05/03/error-vs-exception-part-1/ – Isius

Répondre

0

Vous pouvez modifier createErrorNotifier() pour renvoyer un objet standard contenant à la fois le gestionnaire et le notificateur pour l'instance donnée. Ensuite, vous n'aurez pas besoin de vous inquiéter des getters et de mélanger un handler avec un notifier plus récent. Par exemple, essayez les modifications suivantes:

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

} 

Quand vous appelez createErrorNotifier, vous pouvez accéder à la fois le gestionnaire et notificateur pour une instance donnée:

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

J'espère que cela aide!

2

Il est probablement mieux d'avoir une classe proxy ou un singleton qui vous permettrait d'accéder au gestionnaire d'erreurs lorsque vous en avez besoin.Quelque chose comme:

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

Cela vous permettra de recueillir toujours une seule instance de ErrorHandler (via ErrorHandler :: getInstance()) et également modifier globalement l'instance active chaque fois que vous devez (via ErrorHandler :: setInstance()).

Questions connexes