Page 1 sur 1

Collection d'objects

Posté : 25 mars 2011, 03:37
par devlop78
Bonjour,

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.

Re: Collection d'objects

Posté : 25 mars 2011, 16:22
par devlop78
Bon,

J'ai essayé plusieurs choses, et j'ai vraiment eu mal ;)

Je suis actuellement sur une solution de classe CollectorHelper statique, qui ne possède que des méthodes "d'aide". C'est donc à la classe possédant la collection (je m'amuse à appeler cette classe Collector en clin d'oeil à collectionneur (qui possède des collections ... ;o)) de gérer ses petites affaires. Elle peut donc actuellement créer une collection avec une simple déclaration de variable Array, et créer une méthode add() - là encore, je ne sais pas encore si je vais l'appeler add, ou addXX en fonction de ce que l'on doit ajouter - qui appelera la methode CollectorHelper::add() en lui fournissant : son Array, le type d'objet accepté, et les arguments par défaut (l'objet, et la position). Ensuite, CollectorHelper se charge de vérifier que l'objet respecte bien le type, qu'il n'est pas déjà présent, et la cas échéant, le place à l'endroit voulu (par défaut à la fin, sinon, là où c'est précisé). Je peux ainsi gérer la hierarchie seulement dans les menus (enfin, pas besoin ailleurs), et décider du nom de la méthode, et de ce qu'elle renvoie (par exemple elle même, ou sinon rien).

Re: Collection d'objects

Posté : 25 mars 2011, 16:34
par devlop78
Ouch ! Je commence à développer une hypothèse ... mais c'est pas drole de faire du monologue :

- MovieClip : addChild() Pourquoi pas add() ? Il existe addEventListener() ...
- DOMDocument : On a appendChild, mais aussi la gestion des attributs. Donc add() ou append() serait ambigue.

Hypothèse : on peut partir sur une "règle" qui est que add() si sans ambiguïté et addXX() si ambiguité possible. Actuellement mes menus ne possèdent que des sous menus. Pas d'ambiguité. Mais si je devais rajouter des évenements, etc ... il faudra faire la distinction. En fait, pour comprendre pourquoi ça me tracasse, c'est tout simplement parce que mon composant JavaScript de ma vue possède addFile(), addScript(), etc. Et comme mon travail est avant tout de m'arracher les cheveux pour m'améliorer, la question de la cohérence de code est importante.

Maintenant, peut-être que de façon générale, on évite add() et on favorise addXX(). Avez-vous des exemples connus de classes PHP par exemple qui utilise addXXX() alors qu'il n'y a aucun contexte d'ambiguïté ?