Plusieurs ressources de mon système utilisent le concept de collections d'objets, basé sur les collections de Java.
Cette classe de collection (abstraite) fournit des fonctionnalités de base à une autre classe concrète, appelée Listes, qui permet de trouver des objets grâce aux index de la collection.
J'utiliserai comme exemple ma classe d'en-têtes HTTP pour expliquer.
J'ai, dans son constructeur, une instance de cette classe de listes. Chaque champ d'en-tête HTTP est ajouté à la collection par l'intermédiaire de En-têtes::addHeader() método.
Évidemment, j'ai une getter méthode appelée getHeaders() qui renvoient les Stockage et non celui de la Collection Objet .
Ainsi, si j'ai besoin de lister les en-têtes en dehors de cette classe, il me suffit d'appeler $obj -> getHeaders() et j'ai un ArrayObject avec tous les objets ajoutés.
D'accord !
Mais, récemment, est apparue la nécessité d'utiliser l'une des méthodes de Lists, Listes::find() qui trouve un objet sans même connaître le nom de l'objet ou sa position spécifique dans le stockage de la collection.
Puisque l'objet Lists est dans une propriété privée, Headers::getHeaders() renvoie le Collection Storage et je ne veux pas violer l'encapsulation, en rendant la propriété publique, je ne peux pas accéder à cette méthode.
Tout ce que je code, en plus de la fonctionnalité, doit être visuellement élégant, et créer une autre méthode getter, disons getHeadersLists() produirait une invocation comme :
$obj -> getHeadersLists() -> find( 'foo' );
C'est moche !
J'ai donc rapidement ajouté un __call() dans la classe Headers et cela a bien fonctionné :
$obj -> find( 'foo' );
Mais quelqu'un que je connais (et qui est très versé dans le thème de l'orientation objet) m'a dit que c'était faux.
Mon argument était purement axé sur la lisibilité, et il a rétorqué que "dans l'orientation objet, les méthodes magiques et la lisibilité ne peuvent pas coexister".
Et alors ? Que dois-je faire pour créer ce "pont" entre ces deux classes, sans utiliser de _call() et en préservant les principes de l'Orientation Objet ?
Je sais que je pourrais retourner l'objet Collection dans Headers::getHeaders() et utiliser quelque chose comme :
$obj -> getHeaders() -> find();
Mais ce que j'ai appris sur l'orientation objet, c'est la responsabilité. La responsabilité de cette méthode, comme l'indique sa déclaration, est de renvoyer tous les en-têtes ajoutés et non un objet extérieur.