Design smell : long method
Quoi de plus désagréable que d’arriver dans un code dans lequel les méthodes font 400 à 500 lignes !
Au delà du fait qu’il faut 2 heures pour arriver à comprendre ce que fait cette méthode, "long method" pose 2 problèmes d’architecture : Lorsqu’on jette un oeil à des frameworks tels que le Zend Framework en PHP ouHibernate en JAVA, il est plaisant de constater que beaucoup de méthodes ne dépassent pas 10 à 20 lignes et que les noms choisis sont explicites. En parcourant le code d’une classe, on comprend instantanément son fonctionnement. Evidemment personne n’est là pour fixer un nombre maximum de lignes par méthode. Personnellement je pense que le nombre optimal se situe entre 30 et 40. Comment procéder pour réduire la taille du contenu d’une méthode ? Le cas le plus simple La méthode se contente d’appeler une longue série d’instructions, utilisant des variables locales et renvoyant un résultat. Ma méthode concatène des informations dans une variable avant de la renvoyer On observe souvent ce genre de choses dans du code manipulant des chaînes de caractères, ou des tableaux. Tout le contenu de la méthode accumule des données. Identifier la variable qui collecte les données, puis extraire des sous-méthodes qui prennent en paramètre cette variable et qui contribuent à son "remplissage". Ma méthode contient un switch énorme (aussi appelé râteau) pour traiter les données ou appeler d’autres codes Nicolas le jardinier doit être content. Cependant, nous, développeurs que nous sommes préférons les patterns "command dispatcher" ou "Strategy". Que se passe-t-il si on souhaite rajouter une nouvelle logique ? Et bien il faut modifier le switch appelant. On se retrouve alors avec un couplage fort entre les composants. Les patterns command et strategy, proposent de déléguer à des classes ou des méthodes ces différentes logiques. L’instantiation se fait dynamiquement, par réflexionou via une factory. Rajouter une nouvelle logique revient alors à rajouter une méthode ou une classe, sans toucher à la méthode appelante. Bien utilisé, ce pattern permet d’étendre des fonctionnalités d’un code dont on ne dispose pas des sources. De tous les design smells, je considère celui-ci comme l’un des pires pour la compréhension, la maintenance, les tests, et la réutilisabilité (je viens d’inventer un mot ?) du code. Ces quelques recettes devraient permettre de réduire la taille des méthodes de classe, dans la majorité des cas. Je suis preneur de cas particuliers qui ne seraient pas résolus par les patterns évoqués ci-dessus. A vos claviers !
Dans ce cas, le pattern Extract Method qui propose de découper le contenu en sous ensembles de code, suffira à simplifier la méthode. L’attention doit être portée sur le nom
des "sous-méthodes", afin qu’il soit le plus explicite possible. Attention à leur portées. Dans la majorité des cas, ces méthodes extraites doivent être privées. Inutile d’exposer du code inutilement.
Une solution est d’adopter le pattern "move accumulation to collecting parameters".
On peut trouver ces "conditional statements" dans des codes d’analyses numériques qui appellent un algorithme en fonction de paramètres d’entrées, ou bien dans des servlets ou des contrôleurs qui traitent les requêtes http avant de les dispatcher.