J'ai créé une classe Collection qui me permet de créer une collection d'objets. L'objectif de cette classe était de réellement macher le travail derrière. Un objet CollectionItem a aussi été créé, pour toute hierarchie entre des objets (un menu déroulant par exemple). L'ensemble fonctionne très bien :
Par exemple :
$dialogs = new Collection ('Dialog'); // Je lui dis que je veux une collection d'objets Dialog.
$dialogs->add (new Dialog ());
Par contre, pour mes menus, par exemple, on a :
$menu->add ($item1 = new MenuItem());
$item1->items->add (new MenuItem());
Etc. Le problème, c'est que c'est un peu long, et surtout, qu'à part dans des technos Microsoft, on a surtout, un objet avec des méthodes add et remove et avec une propriété/méthode qui renvoit vers une collection :$node1 = new Node ();
$node1->addChild (new Node());
C'est plus lisible, je trouve, plus simple, plus explicite (ici on a addChild, mais ça peut aussi être addItem() pour un menu), et plus ... j'ai envie de dire "conventionné". Je m'explique aussi : j'utilise des bibliothèques ou des librairies natives ou non : DOMDocument, fait de cette manière. Zend, a apparemment, tendance à le faire: par exemple, $form->addValidation(). C'est aussi assez logique, puisque l'ajout, est largement (sauf pour le cas d'un DOM peut-être) plus utilisé que les autres méthodes (remove, etc). Par exemple, dans mes menus, je ne pense pas utiliser remove() ... Ni pour mes Dialogues ...Alors, pourquoi pose-je ces questions ? Tout simplement parce que j'ai réfléchi à un moyen de faire autrement qu'actuellement, et que je n'ai rien trouvé de concluant. Je précise aussi, que dans mon système, un objet peut posséder plusieurs collection (par exemple, mon objet Javascript possède la collection 'files', 'scripts', et 'onReadyScripts'. Donc si je dois changer, je dois passer de $javascript->files->add() à $javascript->addFile (); Tout de suite, je trouve que ça sonne mieux, mais il faut le prévoir.
- créer une classe abstraite Collector, à qui on dira que telle propriété correspond à une collection, et il se charge de créer la collection. Mais cette objet, qui me parait être un 'outil' deviendrait "mère". Or, j'ai du mal à imaginer "class machin extends Collector". En plus, il faudra, dans le constructeur, ou dans une méthode appropriée, enregistrer les collections. Derrière, il faudra que Collector travail avec __cal(), tout ça, je trouve ça limite, et propice aux bugs en cas de surcharge en oubliant l'appel de la méthode mère. En plus ... On ne peut pas faire d'héritage multiple, et comme mes composants sont susceptibles si besoin, d'avoir des méthodes communes, ça dérange.
- Laisser comme ça ...
- Créer un objet collection pour le parcours d'un objet et des méthodes pratiques (ça ça va), mais réécrire à chaque fois des méthodes add() avec vérification du type en entrée, de la non existance de l'objet déjà dans la collection, de la gestion des parents (ça encore, c'était pour le fun), etc ... Bref, tout ce que gère ma classe Collection et CollectionItem actuellement, à réécrire à chaque fois.
- Garder l'objet Collection mais ajouter des "alias" dans les classes possédant des collections. C'est encore une fois de la réecriture, mais beaucoup moins.
- Autre (Design Pattern, etc ...).
Autre question :
- Que pensez-vous d'une méthode statique create() qui renvoie une nouvelle instance, et de mutateur qui renvoie l'objet en cours, pour faire des méthodes à la chaine : MenuItem::create()->setTitle('x')->setLink('mapage.html'); ?? Encore une fois, de la réécriture, et pas forcément partout, pas toujours utilisé, etc.
- Accéder aux collections, par exemple, avec un accesseur, est assez peu ... naturel. Par exemple : $item->getItems()->add() serait mieux en $item->items->add(). Mais par ailleurs, je préfère la syntaxe setTitle() que title = ; et getTitle() ne me dérange pas. C'est à la manière de JAVA et au moins c'est net, ça évite les __set et __get (oui, toujours du contrôle d'entrée). Quelle règle connaissez-vous ? Par exemple, propriétés en mutateurs et accesseurs méthodes et les collections en "public" apparent (mais dynamiquement géré) ?
Voilà. J'ai bien avancé sur mon projet ; Ca fait un peu framework, mais ça avance ... Par contre, j'ai passé beaucoup d'heures de réflexion sur cette histoire de collections.