Les design patterns sont des solutions à des problèmes de conception logicielle que l'on retrouve sans cesse dans le développement d'applications réelles. Les patterns portent sur des conceptions réutilisables et les interactions entre objets. Certains sont très populaires, comme singleton, factory et strategy ; d'autres sont moins utilisés, comme le pattern poids-mouche (flyweight).
Il arrive que des développeurs implémentent mal les patterns, ce qui peut introduire des problèmes de conception et réduire leurs bénéfices. Il est utile d'identifier les patterns mal implémentés et de corriger leur implémentation.
Pour détecter ce genre de problèmes, nous avons besoin d'un maximum d'informations sur le code source, notamment :
- Les attributs des classes, méthodes et champs.
- Les relations d'héritage entre classes.
- Les dépendances entre classes, méthodes et champs.
- Les endroits où les classes sont instanciées.
génère un modèle de code qui contient toutes ces données et vous permet de l'interroger à l'aide de CQLinq. Essayons de détecter la mauvaise utilisation de deux patterns : Singleton et Strategy.
Singleton
Le pattern singleton est un design pattern qui restreint l'instanciation d'une classe à un seul objet. Cependant, l'usage de ce pattern est devenu controversé, et tous les architectes et concepteurs ne le recommandent pas ; voici un article sur la controverse du singleton.
Une erreur courante lors de l'implémentation du pattern Singleton consiste à ne pas rendre le constructeur privé.
La requête suivante détecte toutes les classes présentant les mêmes caractéristiques qu'un singleton — c'est-à-dire les classes contenant un champ statique se référençant elles-mêmes et une méthode statique renvoyant ce champ — mais sans constructeur privé.

Strategy
Il existe de nombreuses situations où des classes ne diffèrent que par leur comportement. Dans ce cas, il est judicieux d'isoler les algorithmes dans des classes séparées, afin de pouvoir sélectionner différents algorithmes à l'exécution. Le pattern strategy est un bon candidat pour ce genre de besoins.
Voici le diagramme UML de ce pattern :

Comme le montre le diagramme, la classe contexte utilise la classe abstraite « Strategy » et n'a aucune connaissance des implémentations concrètes. Cependant, dans certaines implémentations, les classes concrètes sont utilisées directement par la classe contexte. Voici un exemple de cette erreur :

Recherchons avec CQLinq toutes les classes utilisant ce pattern strategy. Pour cela, nous pouvons rechercher les classes abstraites ayant plusieurs classes dérivées où le client utilise directement les méthodes des implémentations concrètes au lieu de la classe abstraite.

Le résultat de cette requête nous donne les types dérivés utilisés directement par d'autres méthodes au lieu des types abstraits. Il vous suffit ensuite de trouver les méthodes qui les utilisent pour déterminer où l'implémentation du pattern Strategy devrait être corrigée.
Cependant, cela n'identifiera pas les emplacements exacts où le pattern Strategy est mal implémenté. En revanche, cela met en évidence des zones potentiellement problématiques qu'un développeur peut ensuite examiner manuellement.
Conclusion
Les design patterns peuvent améliorer la qualité de la conception. Cependant, s'ils sont mal implémentés, ils peuvent devenir une source de problèmes et de bugs.
