PHP Méthode d'enchaînement en PHP


Exemple

Le chaînage des méthodes est une technique expliquée dans le livre de Martin Fowler, Domain Specific Languages . Le chaînage des méthodes est résumé comme

Les méthodes de modification Makes renvoient l'objet hôte afin que plusieurs modificateurs puissent être appelés dans une seule expression .

Considérez ce morceau de code non-chaîné / régulier (porté sur PHP à partir du livre susmentionné)

$hardDrive = new HardDrive;
$hardDrive->setCapacity(150);
$hardDrive->external();
$hardDrive->setSpeed(7200);

Le chaînage des méthodes vous permettrait d'écrire les instructions ci-dessus de manière plus compacte:

$hardDrive = (new HardDrive)
    ->setCapacity(150)
    ->external()
    ->setSpeed(7200);

Tout ce que vous devez faire pour que cela fonctionne est de return $this dans les méthodes que vous voulez enchaîner:

class HardDrive {
    protected $isExternal = false;
    protected $capacity = 0;
    protected $speed = 0;

    public function external($isExternal = true) {
        $this->isExternal = $isExternal;        
        return $this; // returns the current class instance to allow method chaining
    }

    public function setCapacity($capacity) {
        $this->capacity = $capacity;        
        return $this; // returns the current class instance to allow method chaining
    }

    public function setSpeed($speed) {
        $this->speed = $speed;        
        return $this; // returns the current class instance to allow method chaining
    }
}

Quand l'utiliser

Les principaux cas d'utilisation du chaînage de méthodes sont la création de langages internes spécifiques au domaine. Le chaînage de méthode est un bloc de construction dans Expression Builders et Fluent Interfaces . Ce n'est pas synonyme de ceux, cependant . Le chaînage des méthodes ne permet que ceux-là. Citant Fowler:

J'ai également remarqué une idée fausse commune - beaucoup de personnes semblent assimiler des interfaces fluides avec le chaînage des méthodes. Certes, le chaînage est une technique courante à utiliser avec des interfaces fluides, mais la fluidité réelle est bien plus que cela.

Cela dit, l'utilisation de Chain Chaining pour éviter d'écrire l'objet hôte est considérée comme une odeur de code par beaucoup. Cela rend les API non évidentes, en particulier lors du mélange avec des API non chaînées.


Notes complémentaires

Séparation des requêtes de commande

La séparation des requêtes de commande est un principe de conception mis en avant par Bertrand Meyer . Il déclare que les méthodes de mutations d'état ( commandes ) ne doivent rien renvoyer, alors que les méthodes renvoyant quelque chose ( requêtes ) ne doivent pas muter. Cela facilite la compréhension du système. Le chaînage des méthodes viole ce principe parce que nous modifions l'état et renvoyons quelque chose.

Getters

Lorsque vous utilisez des classes qui implémentent le chaînage de méthodes, faites particulièrement attention lorsque vous appelez des méthodes getter (c'est-à-dire des méthodes qui renvoient autre chose que $this ). Puisque les getters doivent retourner une valeur autre que $this , le chaînage d'une méthode supplémentaire sur un getter fait que l'appel opère sur la valeur obtenue , pas sur l'objet d'origine. Bien qu'il existe des cas d'utilisation pour les getters chaînés, ils peuvent rendre le code moins lisible.

Loi de Déméter et impact sur les tests

Le chaînage de méthode tel que présenté ci-dessus ne viole pas la loi de Demeter . Cela n'a pas non plus d'impact sur les tests. C'est parce que nous retournons l'instance hôte et non un collaborateur. C'est une idée fausse courante provenant des personnes qui confondent le chaînage des méthodes avec les interfaces fluides et les générateurs d'expressions . Ce n'est que lorsque le chaînage des méthodes retourne d' autres objets que l'objet hôte que vous violez la loi de Demeter et obtenez des falsifications dans vos tests.