Je ne suis toujours pas convaincu par un design avec decorators. Même si on pourrait probablement imaginer une voie détournée pour simplifier ce genre d'écriture:
$article = new TrashDecorator( new TranslateDecorator( new ArticleModel() ) );
... je pense toujours que ça va créer plus de problèmes que ça ne va en résoudre. En partie parce que dans les exemples présentés, il va falloir se trimbaler "new TrashDecorator( new TranslateDecorator(" dès qu'on manipule un article. Et en partie aussi à cause de ceci:
$article = $article->findOne( 4 );
Dans le context qui est le notre, nos objets du model ont théoriquement une sémantique d'unicité très forte (orm). Or retourner un $this modifié comme présenté juste au dessus est une abération (en ce qui me concerne ).
Je pense que ce n'est pas pour rien que dans la plupart des orm existants, on passe par une classe spécialisée (qui peut encapsuler une table par exemple) ou des méthodes statiques pour rapatrier ou créer de nouveaux objets. C'est le cas dans Propel ou Doctrine et d'autres. D'ailleurs, Doctrine fonctionne avec un mécanisme d'observers (entre autres).
Une fois qu'un objet du model est créé, il ne devrait jamais changer (dans le sens, modéliser une autre entité de la db, souvent un row). L'objet peut être référencé à plusieurs endroits différents d'un code php et si on le modifie radicalement à un endroit, ça aura des répercussions généralement non voulues ailleurs. Et là je ne considère même pas le fait qu'un objet puisse être transformé en un groupement d'objets avec findAll().
Il y a toujours l'option du clonage (clone en php), mais l'architecture à base de decorators ne s'y prête pas bien.
Mon point de vue est forgé par une vision très orm du problème. Finalement je me dis que ce n'est probablement pas tout à fait ce que tu souhaites faire.
Par exemple le concepte d'EmptyTrash, dans un cadre orm, ça ne devrait pas être une propriété de chaque entité du model, mais plutôt un truc "haut dessus". Une facilité pour manipuler un groupement d'objets. Les observers dans mon premiers posts n'auraient d'intéret que pour effectuer des opérations sur l'instance unique à laquelle ils sont rattachés (par exemple vérifier un bon format des données avant d'être sauvegardé en table, ou déclencher des opérations annexes (invalider du cache, logger, vérifier des droits etc)).
Partager