2017-02-24 2 views
0

Je souhaite créer un validateur personnalisé. Mais je ne veux pas appeler new à chaque fois, car cela rend plus difficile à tester. Je pense aussi App::make est un peu moche. Je veux juste Dependency Injecter mon validateur personnalisé et l'utiliser.PHP pseudo immutable objet utilisant clone

Mes pensées sur la façon d'y parvenir sont en utilisant clone. Appelant la méthode validate, définirait les propriétés sur le clone, plutôt que $ this. Ainsi, la version DI de la classe reste intacte. Il est également très facile de tester/simuler de cette façon.

Est-ce un modèle approprié/Dois-je simplement utiliser new?

Mon validateur personnalisé

class CustomValidator 
{ 
    protected $rules = [ 
     'key' => 'required', 
    ]; 

    protected $errors = []; 

    public function validate(array $event): CustomValidator 
    { 
     $v = Validator::make($event, $this->rules); 

     if ($v->fails()) { 
      $copy = clone $this; 
      $copy->errors = $v->errors()->toArray(); 

      return $copy; 
     } 

     return $this; 
    } 

    public function hasErrors(): bool 
    { 
     return !empty($this->errors); 
    } 

    public function getErrors(): array 
    { 
     return $this->errors; 
    } 
} 

Utilisation:

foreach ($events as $event) { 
    // customValidator is immutable. $v is cloned 
    $v = $this->customValidator->validate($event); 

    if ($v->hasErrors()) { 
     // do something with $v->errors(); 
     continue; 
    } 

    // No errors... Do something else 
} 
+0

Eh bien, si 'App :: make' semble laid, alors Laravel est probablement pas la meilleur choix. Il est assez idiomatique d'utiliser le conteneur, et le framework s'appuie fortement dessus. Par défaut, 'bind' enregistre les services non partagés, c'est-à-dire que vous obtenez une nouvelle instance du conteneur. –

+0

Ce n'est pas seulement que 'App :: make' est moche. OMI - en utilisant le clone, cela réduit la probabilité d'erreurs. par exemple. oublier 'App: make' ou oublier 'new' donnerait des bugs dans les prochaines itérations. par exemple. en remplissant le tableau 'errors', et cet artefact restant dans les appels suivants - même ailleurs dans le code. – Gravy

+0

Je ne suis pas du tout certain de comprendre comment * oublier * pour 'App :: make' est pire que' oublier 'de' clone', mais c'est vraiment une question de goût dans votre cas. D'une manière générale, le clonage est légèrement différent, puisque le clone partage les mêmes instances d'objets injectés, ce qui peut ou non être un comportement souhaité. –

Répondre

0

clone est tout à fait valable et est souvent utilisé pour immuabilité d'objets dans les API syntaxed couramment. Donc je ne vois pas de problème là-bas.

Je pense que vous aurez des commentaires sur semi-immuabilité bien, mais je pense personnellement que c'est une solution raisonnable à votre problème