Cet article est publié sous licence CC BY-NC-SA
Un adage bien connu dans la communauté Rails est celui du « Fat Model, Skinny Controller », autrement dit : le code décrivant les comportement et les interactions entre objets doit se trouver principalement dans les modèles, les contrôleurs ne servant qu’au traitement et à l’enchaînement des actions de l’utilisateur.
Si l’idée d’avoir des contrôleurs légers et simples est bonne, pourquoi vouloir mettre tout le reste du code dans les modèles ? Ceci pose en fait plusieurs problèmes.
Le problème est pourtant assez simple à résoudre, il faudra plutôt suivre la devise « Skinny Model, Skinny Controller ».
L’idée là derrière est de pouvoir décrire les comportements et interactions entre les différentes entités modélisant le domaine de notre application sans avoir à se soucier de la partie Rails, qui ne sera présente que pour offrir une représentation applicative de ce domaine aux utilisateurs.
Lorsqu’on part d’une application vierge, ces principes sont assez faciles à mettre en place : il faut dès le départ développer une vision concentrée sur le métier de l’application d’après ses spécifications.
On peut dès ce moment commencer à coder des classes et modules sans faire intervenir Rails. Un très bon exemple de ce workflow est visible dans les screencasts Destroy All Software, et notamment la série Sucks/Rocks.
Développer de cette manière permet de rendre ses tests plus faciles à implémenter, et plus rapides à exécuter (on n’a pas besoin de charger la stack Rails pour ses tests).
Dans le cas où on part d’une application existante, on va plutôt suivre une approche d’extraction, en repérant les classes assurant plusieurs responsabilités.
Un exemple simple est celui d’un modèle qui embarque du code de présentation : celui-ci peut être extrait dans une classe qui utilise l’objet modèle en dépendance.
Dans tous les cas, la suite de tests doit être tenue à jour rigoureusement afin d’assurer la justesse de la modélisation et l’absence de régressions dans le cas d’extractions.
Ces préceptes imposent forcément la création de plus de fichiers que ceux contenus dans une application Rails standard. Le problème qui se pose alors est de pouvoir organiser ces fichiers de façon sensée.
On retrouvera souvent une structure de la forme suivante :
├── app/ │ ├── controllers │ ├── models │ ├── views │ ├── services │ └── policies └── lib/ ├── toto/ ├ ├── classe_metier.rb ├ └── module_metier.rb └── toto.rb
Les dossiers dans app/
contiendront uniquement des composants de l’application
Rails. Dans l’exemple ci-dessus, les services
sont des utilitaires permettant
d’implémenter des actions complexes ou faisant intervenir des ressources
externes.
Les policies
sont responsables de la gestion des actions de lecture
complexes. On peut introduire d’autres concepts, l’important est de distinguer
ces objets et de ne pas intégrer leurs fonctionnalités dans les modèles ou les
contrôleurs.
Dans lib/
on a les fichiers concernant le domaine purement métier de notre
application, correctement namespacés sous un module du nom de notre application.
Ici, on est libre d’organiser le code comme bon nous semble, selon ce qui
nous paraît le plus juste.
Libre à vous d’adapter cette structure, voire d’en extraire des bibliothèques réutilisables sous forme de gems. C’est d’ailleurs un des autres avantages à suivre cette approche.
Adopter une telle démarche lors du développement permet rapidement de simplifier son développement et surtout de rendre les applications plus faciles à maintenir.
Comme souvent, ça n’est pas un remède en soi à tous les maux qui peuvent affecter un projet, mais c’est un premier pas significatif vers une meilleure hygiène de code.
Je vous encourage fortement à vous renseigner sur le principe SOLID, dont les initiales correspondent à l’ensemble des principes suivants :
Le livre Practical Object-Oriented Design in Ruby de Sandy Metz est aussi riche d’enseignements sur l’écriture de code orienté objet et la conception d’applications suivant ce paradigme.
Pour aller un peu plus loin sur la partie code de ces principes, je vous recommande la lecture de 7 Ways to Refactor your Fat ActiveRecord Models et Your Objects, The Unix Way sur le blog de CodeClimate.
N’oubliez pas : un code bien conçu est plus facile à appréhender pour une personne découvrant le projet (ça peut être vous dans quelques mois), il faut donc soigner cet aspect, et ces techniques sont là pour ça.
L’équipe Synbioz.
Libres d’être ensemble.
Nos conseils et ressources pour vos développements produit.