Code smell

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher

En génie logiciel, les code smells ou mauvaises odeurs sont des mauvaises pratiques de conception logicielle qui conduisent à l'apparition de défauts. Ces défauts sont souvent issus de mauvais choix d'implémentations ou de conceptions et conduisent à une complexification du code source et de la maintenance et évolutivité de celui-ci. Afin de corriger un code smell, il est nécessaire de procéder à un réusinage du code source, c'est-à-dire modifier le code sans en altérer son comportement.

Exemples de code smells[modifier | modifier le code]

A la manière des patrons de conceptions, de nombreux exemples de code smells ont été répertoriés et décrits dans la littérature scientifique.

Martin Fowler en a notamment répertorié des dizaines ainsi que la refactorisation à adopter[1].

Duplicated Code[2][modifier | modifier le code]

L'anti-patron Duplicated Code est un exemple de code smell classique. Il s'agit de trouver la même portion de code à plusieurs endroits d'une application.

La duplication de code peut se situer dans une même classe, au sein de méthodes différentes, ou dans des classes différentes.

Feature Envy[3][modifier | modifier le code]

L'anti-patron Feature Envy décrit une méthode qui fait de nombreux appels à des méthodes d'autres classes. Le plus souvent ces appels sont faits à des getters (ou accesseurs) par besoin de données.

C'est le signe que la méthode se trouve probablement dans la mauvaise classe.

BLOB[4][modifier | modifier le code]

Aussi connu sous le nom de God Class ou Winnebago, l'anti-patron Blob est une classe ayant trop de responsabilités au sein du logiciel.

Cela se manifeste par un trop grand nombre d'attributs et de dépendances aux classes data, ainsi qu'un nombre d'appels de ces méthodes par les classes extérieures très important.

Long Parameter List[5][modifier | modifier le code]

L'anti-patron Long Parameter List est une erreur héritée des débuts de la programmation, avant l'arrivée de l'orienté objet. Chaque fonction nécessitait toute une série de paramètres, qu'il était préférable d'utiliser à la place des variables globales. Mais aujourd'hui et depuis l'arrivée des langages orientés objets, la situation a évolué et le surnombre de paramètres ne fait que nuire à la lisibilité et la compréhension. Cela complique également l'utilisation et la refactorisation du code.

Long Method[5][modifier | modifier le code]

L'implémentation de longues méthodes est un problème récurrent chez les développeurs débutants. Il s'agit de rendre les méthodes inutilement longues et complexes quand il est possible de les décomposer.

Cette décomposition en plus d'améliorer la lisibilité et la compréhension d'un code, permet de simplifier la refactorisation par la suite. On la caractérise souvent par l'utilisation d'un trop grand nombre de paramètres internes, de boucles ou conditions ainsi que de valeurs de retour.

Large Class[2][modifier | modifier le code]

l'anti-patron Large Class décrit simplement le cas d'une classe possédant beaucoup de variables. Ce genre de situation induit parfois une utilisation séparée des variables et conduit le plus souvent vers de la duplication de code.

Détection et correction de code smells[modifier | modifier le code]

Moyens de détection[modifier | modifier le code]

Pour chaque code smell, il existe des moyens de détection plus ou moins mathématiques ainsi que des pratiques permettant de corriger ou même éviter l'erreur. Pour chacun des six code smells précédents, voici la méthodologie de correction ainsi que le moyen de détection à adopter.

Duplicated Code[modifier | modifier le code]

Pour détecter le smell Duplicated Code (code dupliqué littéralement), il faut mesurer le pourcentage de lignes dupliquées dans le logiciel. Cela peut paraître assez simple d'un premier abord, mais un morceau de code peut être dupliquée de différentes manières. La détection du duplicata exact est triviale, mais dans certains cas, il faut aussi être capable de gérer le renommage ou l'alias.

Par exemple en Java :

Integer var = 5;
String str = String.valueof(var);

est la duplication de code de :

Integer nombre = 5;
String chaine = String.valueof(nombre);

Si tel est le cas, il faut donc que l'algorithme de détection teste toutes les possibilités de renommage pour être bien certain de ne pas manquer un doublon de code. De plus, il est tout à fait possible que la duplication de code ait été modifiée légèrement. Pour reprendre notre exemple précédent, il faudrait aussi prendre en compte les cas suivants :

Integer var = 5;
// Du code ne modifiant pas var...
String str = String.valueof(var);

Dans d'autres cas, il se peut que deux algorithmes différents fassent le même travail. Le cas échéant, l'algorithme le plus optimisé est sélectionné et utilisé pour les deux appels. Cette erreur est souvent commise par les débutants suite à des abus de copier/coller. En plus d'augmenter sensiblement la taille du code source, elle engendre également des problèmes lors de la maintenance. Pour corriger ce problème, il faut extraire le code dupliqué et le déplacer dans une nouvelle méthode et remplacer les anciens codes par des appels à cette nouvelle méthode. Enfin, il est possible de l'éviter en s'imposant les bonnes pratiques de développement suivantes :

Feature Envy[modifier | modifier le code]

Le smell Feature Envy (littéralement« caractéristiques jalouses ») survient dans une classe quand une méthode est plus intéressée par les membres (attributs et méthodes) d'une autre classe que les siens. Pour corriger ce genre de problème au sein d'une classe, plusieurs solutions :

  • Déplacer une méthode d'une classe dans une autre si elle utilise plus les données de celle-ci que les siennes.

Par exemple, dans la classe Rectangle, la méthode perimetre() peut être totalement déplacée dans la classe AutreClasse.

public class Rectangle {

   ...

   public Double perimetre() {
        return 2 * AutreClasse.largeur + 2 * AutreClasse.longueur;
   }

}
  • Déplacer une partie d'une méthode dans une autre si elle accède aux données d'une autre classe plus que les siennes. Même principe avec une méthode accédant aux données de plusieurs classes.

Par exemple, dans la classe bateau, la méthode preparer_bateau() utilise plus d'appels de méthodes de la classe SPI que ses propres méthodes.

public class Bateau {

   private SPI spi;
   private Reserve reserve;

   ...

   public void preparer_bateau() {
        this.laver();
        this.verifier_coque();
        reserve.verifier_provisions();
        spi.regler_hauteur();
        spi.regler_largeur();
        spi.verifier_voile();
   }

}

La correction adaptée serait donc de créer une méthode dans SPI regroupant les trois appels et d'appeler cette nouvelle méthode dans preparer_bateau().

Pour détecter le code smell Feature Envy, il faut être capable de localiser les méthodes utilisant trop les méthodes d'une classe extérieure. Pour cela, il faut mesurer la force de couplage qu'ont les méthodes d'une classe avec les autres méthodes ou données de classes extérieures. Lanza et Marinescu proposent une formule conditionnelle de détection basée sur des métriques[6] :

Avec :

  • 5, une valeur fixée et expliquée dans leur ouvrage.
  • LAA (Locality of Attribute Accesses) qui représente la proportion de méthodes de la classe utilisant accédant à plus d'attributs de classes extérieures qu'à ses propres attributs.
  • FDP (Foreign Data Providers) qui représente la proportion d'utilisation d'attributs "extérieurs" et utilisés dans très peu d'autres classes.
  • ATFD (Access to Foreign Data) qui représente la proportion de méthodes de la classe qui accèdent aux attributs directement ou via des accesseurs d'autres classes extérieures.

Cette méthode de détection est utilisée dans les outils iPlasma et inFusion. D'autres outils comme JDeodorant, essayent de déplacer les méthodes dans des autres classes. Ainsi pour chaque méthode du programme, un algorithme va former une liste de classes candidates où il est possible de déplacer la méthode. Ensuite, pour chacun de ces candidats, un calcul de distance sera effectué ainsi qu'un calcul sur le nombre d'appels d'accesseurs. À la fin, la classe sélectionnée est celle dont la distance calculée est minimale et le nombre d'appels d'accesseurs maximal[7],[8]. Autre approche avec un outil nommé HIST basé sur l'analyse de commits, une méthode affectée par le Smell Feature Envy a tendance à changer plus fréquemment avec les méthodes des autres classes qu'avec celles de sa propre classe[9]. Enfin, il existe également un plugin Eclipse permettant de détecter cette erreur. Ce greffon nommé Eclipse Metrics[10] calcule un indice de jalousie maximal et dès que cet indice est dépassé, l'utilisateur est informé via un message d'avertissement.

BLOB[modifier | modifier le code]

Cette erreur est l'impact direct de l'incapacité à concevoir correctement des architectures logicielles complexes dans un langage de programmation procédural. En plus d'être totalement inélégant, le programme perd en vitesse d’exécution et la classe est difficilement maintenable. Il est possible de l'éviter en s'imposant les bonnes pratiques de développement suivantes :

Il n'y a pas de correction miracle pour un tel cas, il faut repenser son code afin de le factoriser. La taille de la classe n'est pas liée à cette erreur de conception. D'une manière générale, voici les corrections typiques

  • Retirer les méthodes n'ayant aucun impact sur la classe en question et les replacer dans la classe impactée par l'appel de la méthode.

Ainsi, dans la classe ci-dessous, la méthode afficher_pilote() devra être déplacée dans la classe Pilote...

public class Avion {

   private Pilote pilote;

   ...

   public String afficher_pilote() {...}

}
  • Retirer les attributs présents illogiquement dans la classe et les placer dans les classes adaptées.

Ainsi, dans la classe ci-dessous, l'attribut matricule_pilote devra être déplacée dans la classe Pilote...

public class Avion {

   private Pilote pilote;
   private String matricule_pilote;

   ...

}
  • Retirer les associations dont l’existence n'est pas nécessaire.

Ainsi, dans la classe ci-dessous, la référence pilote devra être déplacée dans la classe Equipage...

public class Avion {

   private Equipage equipage;
   private Pilote pilote;

   ...

}

Pour la détection, Lanza et Marinescu proposent la formule conditionnelle suivante reposant sur trois métriques[11] :

Avec :

  • 47 et 5, des valeurs fixées et expliquées dans leur ouvrage.
  • WMC (Weighted Method Count) qui représente la somme de la complexité statistique de toutes les méthodes dans une classe.
  • TCC (Tight Class Cohesion) qui représente le nombre relatif de méthodes accédant aux attributs.
  • ATFD (Access to Foreign Data) qui représente le nombre de classes externes qui accèdent aux attributs de la classe directement ou via des accesseurs.

Cette méthode de détection est utilisée dans les outils iPlasma et inFusion.

DECOR utilise des fiches de règles nommées "Rules Cards"[12]. D'après les caractéristiques de ces "Rules Cards", un BLOB est une classe ayant un LCOM5 (un manque de cohésion de méthodes, Lack of Cohesion Of Methods en anglais) supérieur à 20 et un nombre de méthodes et d'attributs supérieurs à 20. De plus, les classes sont identifiables par des noms suspects comme Process, Control, Manage, System etc[13]...

Pour connaître le LCOM5 d'une classe, on utilise la formule ci-dessous[14] :

Avec :

  • l, le nombre d'attributs
  • k, le nombre de méthodes
  • a, la somme du nombre d'attributs distincts accédés par chaque méthode dans une classe

D'autres outils comme JDeodorant essayent de décomposer la classe en plusieurs afin de déterminer si la classe est un BLOB[15]. Cette décomposition s'effectue par clustering, s'il est possible de partitionner de manière optimale les méthodes dans différentes classes alors c'est un BLOB. Pour former les différents clusters, on utilise alors entre les membres (attributs, méthodes, etc.) de la classe, la distance de Jaccard définie ainsi[16],[8] :

Enfin, avec HIST, outil basé sur l'analyse de commits, on peut détecter un BLOB car c'est une classe qui change régulièrement dans le temps [17].

Long Parameter List[modifier | modifier le code]

Le code smell Long Parameter List (longue liste de paramètres littéralement) survient dans les classes contenant une méthode ayant trop de paramètres. Cette erreur est typiquement commise lors de la fusion de plusieurs algorithmes en un seul. Autre possibilité, lorsqu'un développeur essaye de rendre une classe trop paramétrable. Généralement, il est fort difficile de comprendre ces listes de paramètres tant qu'elles deviennent assez vite contradictoires et difficiles à utiliser concrètement.

Voici des exemples de corrections possibles :

  • Retirer les paramètres résultant d'appels de méthodes sur un autre objet, l'objet en question peut être placé dans le domaine de sa classe ou utilisé comme paramètre.

Par exemple, si les derniers paramètres de la fonction calcul() sont issus d'un objet Mesures :

public void calcul( ...., int x, int y, int z) {

    ...

}

Il est alors directement possible de passer l'objet Mesure en paramètre.

public void calcul( ...., Mesures mesures) {

    ...

}
  • Regrouper les paramètres pouvant l'être et passer l'objet ainsi créé dans la méthode.

Pour reprendre l'exemple précédent, même si les paramètres x, y et z sont totalement indépendants, il est possible de créer un objet pour réduire le nombre de paramètres.

public void calcul( ...., int x, int y, int z) {

    ...

}

Encore une fois, Il est envisageable de passer ce nouvel objet créé par en paramètre.

public Objet creer_objet(int x, int y, int z) {

    ...

}

public void calcul( ...., Objet valeurs) {

    ...

}

Pour ce qui est de la détection, il suffit de compter le nombre de paramètres d'une méthode ! Chaque outil de détection a son nombre maximum autorisé. Par exemple, PMD a pour valeur maximale 10 et Checkstyle 7[18].

Long Method[modifier | modifier le code]

Le code smell Long Method (longue méthode littéralement) survient dans les classes contenant une méthode ayant trop d'instructions. Cette erreur est généralement commise par les développeurs ne décomposant pas suffisamment leurs codes. Pour éviter de telles erreurs, un développeur peut adopter les mêmes principes de développement cités dans la partie sur le Duplicated Code : Travailler en TDD ou factoriser son code en partitionnant le code en petites méthodes. Pour détecter ce code smell, il ne suffit pas de compter le nombre de ligne de codes des méthodes. En effet, dans certains cas, il est réellement nécessaire d'avoir autant de codes quand il n'est pas fractionnable. On ne peut donc pas créer des moyens de détection comme pour le Long Parameter Method.

Mäntyla suggère d'utiliser pour la détection la complexité cyclomatique ainsi que les métriques d'Halstead[19].

Cependant, certain outil détecte ce smell uniquement en comptant le nombre de ligne de codes NLOC. C'est le cas de Checkstyle qui considère qu'une méthode est longue à partir de 150 lignes et PDM à partir de 100 lignes[18] JDeodorant utilise des techniques de tranchage pour déterminer si une méthode peut être scindée en plusieurs autres.

Large Class[modifier | modifier le code]

Le smell Large Class (classe large littéralement) est une classe contenant trop de responsabilités. Cette erreur est souvent commise par le développeur débutant négligeant les principes de l'orienté objet. La NASA Software Assurance Technology Center a publié les valeurs seuils recommandées pour éviter de créer une Large Class. Selon elle, une classe a trop de fonctionnalités quand l'une des conditions suivantes n'est pas valide[20] :

  • Le nombre de méthodes dans la classe est inférieur à 20
  • Le poids des méthodes par classe est inférieur à 100
  • Le nombre de méthodes et le nombre de méthodes invoquées par chacune de ces méthodes est inférieur à 100
  • Le nombre de classes référencées dans la classes est inférieur à 5

On peut aussi compter le nombre de lignes de la classe (souvent appelé NLOC pour number of lines of code) et le comparer à un maximum que l'on s'impose. Par exemple, PMD considère qu'une classe est large si elle contient plus de 1000 lignes de codes et Checkstyle 2000 lignes[18]. Cependant, il est possible de faire des exceptions pour les classes contenant des interfaces graphiques pour l'utilisateur (GUI). Pour corriger ce problème, il faut réduire les responsabilités de la classe en question en restructurant le code en différentes classes de faibles responsabilités. Outre le gain de clarté après la restructuration, la maintenance du programme sera plus aisée.

Outils existants[modifier | modifier le code]

Il existe de plus en plus d'outils de détection automatique de ces mauvaises pratiques de conception. Voici une liste non exhaustive des principaux outils existants.

DECOR[modifier | modifier le code]

Proposé par Naouel Moha, DECOR[21] pour Detection&Correction, est un outil qui consiste en la détection et la correction automatique des code smells. Le processus est décomposé en deux parties, DETEX et COREX, qui font la spécificité de cette méthode.

Tout d'abord, la détection est assurée par un ensemble de règles qu'il faut spécifier à l'aide d'un langage de haut niveau.

Ensuite, l'utilisateur suggère ses restructurations de codes souhaitées, de nouveau grâce à l'utilisation du même langage.

Enfin, l'outil se charge d'analyser et corriger automatiquement les défauts dans le code, en se basant sur les règles décrites au préalable.

Cette méthode englobant à la fois la détection et la correction présente l'avantage d'automatiser l'ensemble du processus sans faire intervenir manuellement le développeur pour chaque correction détectée.

DECOR est aujourd'hui capable de détecter 19 code smells différents parmi lesquels on trouve le Blob, Long Method ou Long Class par exemple[22].

inFusion[modifier | modifier le code]

L'outil inFusion est une solution commerciale clé en main à destination des développeurs et basé sur l'outil iPlasma.

Il présente l'avantage d'être un outil complet avec sa propre interface pour être utilisé de façon indépendante.

Il est capable de détecter plus de 20 code smells parmi lesquels Duplicated Code, Blob, Long Method ou Long class.

inFusion gère également l'analyse de code Java, C ou C++.

JDeodorant[modifier | modifier le code]

Présenté sous la forme d'un plugin pour l'environnement de développement Eclipse[23] développé par les équipes de l'Université Concordia au Canada et l'Université de Macédoine en Grèce.

L'outil qui s'utilise donc directement dans l'éditeur permet de détecter des code smells et de proposer la refactorisation appropriée.

Il est à ce jour capable de détecter 5 cas de code smells, Feature Envy, Type-Checking, Long Method, Blob ou encore Duplicated Code.

JDeodorant[24] possède plusieurs avantages, notamment :

  • Pré-évaluation des effets de chaque solution proposée
  • Guidage de l'utilisateur dans la compréhension des erreurs de conception.
  • Simplicité de l'outil, "one-click approach".

Stench Blossom[modifier | modifier le code]

L'outil Stench Blossom[25] est un détecteur de code smells qui fournit un environnement interactif qui permet aux développeurs de visualiser rapidement les smells contenus dans leur code.

La rétroaction est synthétique et visuelle et offre des informations très détaillées sur l'origine de l'erreur sous la forme d'ensemble de pétales.

Plus l'erreur est importante et plus le pétale est grand. Le développeur peut alors voir directement quelle erreur est la plus importante en regardant l'ensemble créé et corriger son code en conséquence.

Stench Blossom est un plugin Eclipse qui détecte 8 mauvaises odeurs dans des codes Java.

HIST[modifier | modifier le code]

L'outil HIST, pour Historical Information for Smell deTection [26], est un outil de détection de code smells apportant la particularité d'une approche basée sur l'historique d'un gestionnaire de versions, en plus de l'analyse statique de code habituelle.

La présence de problèmes de conception au sein d'un code source oblige les développeurs à adopter un comportement spécifique lors d'une modification du programme. Ces comportements sont ensuite détectables grâce à l'historique du gestionnaire de versions. HIST propose donc de repérer ces refactorisations particulières via la mise en place de patrons de détections spécifique à un code smells.

HIST prend en charge 5 code smells parmi les plus connus, Divergent Change, Shotgun Surgery, Parallel Inheritance, Blob et Feature Envy.

Par exemple, la détection du code smell Blob par l'utilisation d'un historique se base sur le comportement de refactorisation. En effet, quand une classe Blob est présente dans un programme, la probabilité que cette classe soit modifiée lors d'une refactorisation est élevée. Il suffit alors de regarder dans le projet une classe qui est régulièrement modifiée dans un commit impliquant une autre classe[27]. Comparativement à d'autres outils (notamment DECOR), Hist possède un taux de détection plus élevé[28], cependant il nécessite également plus d'informations que le seul code source. De plus, l'analyse de l'historique se présente comme une phase supplémentaire à l'analyse statique, la comparaison n'a donc d'intérêt tant les deux méthodes sont complémentaires.

Autres[modifier | modifier le code]

Bien sûr, beaucoup d'autres outils existent, parmi lesquels Checkstyle ou pMD.

Bibliographie et références[modifier | modifier le code]

Références[modifier | modifier le code]

  1. Refactoring: Improving the Design of Existing Code 1999, p. 63-73
  2. a et b Refactoring: Improving the Design of Existing Code 1999, p. 63-64
  3. Refactoring: Improving the Design of Existing Code 1999, p. 66
  4. Detecting Bad Smells in Source Code using Change History Information 2013, p. 269
  5. a et b Refactoring: Improving the Design of Existing Code 1999, p. 65
  6. Object-oriented metrics in practice: using software metrics to characterize, evaluate, and improve the design of object-oriented systems 2007, p. 85-86
  7. Identification of Move Method Refactoring Opportunities 2009, p. 1-2
  8. a et b Automatic detection of bad smells in code: An experimental assessment 2012, p. 5
  9. Detecting Bad Smells in Source Code using Change History Information 2013, p. 271
  10. http://eclipse-metrics.sourceforge.net/descriptions/pages/FeatureEnvy.html
  11. Object-oriented metrics in practice: using software metrics to characterize, evaluate, and improve the design of object-oriented systems 2007, p. 80-81
  12. DECOR: A Method for the Specification and Detection of Code and Design Smells 2010, p. 3
  13. Anti-Pattern Detection: Methods, Challenges and Open Issues 2014, p. 3
  14. An Effort to Improve Cohesion Metric Using Inheritance 2013, p. 2
  15. Decomposing object-oriented class modules using an agglomerative clustering technique 2009, p. 4
  16. Anti-Pattern Detection: Methods, Challenges and Open Issues 2013, p. 4-5
  17. Detecting Bad Smells in Source Code using Change History Information 2013, p. 270
  18. a, b et c Automatic detection of bad smells in code: An experimental assessment 2012, p. 6
  19. An experiment on subjective evolvability evaluation of object-oriented software: explaining factors and interrater agreement 2007, p. 7
  20. Looking for Patterns in Code Bad Smells Relations 2011, p. 2
  21. DECOR: A Method for the Specification and Detection of Code and Design Smells 2010
  22. DECOR: A Method for the Specification and Detection of Code and Design Smells 2010, p. 15
  23. « JDeodorant », sur Eclipse Plugins, Bundles and Products - Eclipse Marketplace (consulté le 6 décembre 2015)
  24. JDeodorant: Identification and Removal of Type-Checking Bad Smells 2009, p. 1-3
  25. Decomposing object-oriented class modules using an agglomerative clustering technique 2010
  26. HIST : Historical Information for Smell deTection 2013
  27. HIST : Historical Information for Smell deTection 2013, p. 270-271
  28. HIST : Historical Information for Smell deTection 2013, p. 274-275

Bibliographie[modifier | modifier le code]

  • (en) Martin Fowler, « Refactoring: Improving the Design of Existing Code », Addison-Wesley,‎
  • (en) Michele Lanza et Radu Marinescu, « Object-oriented metrics in practice: using software metrics to characterize, evaluate, and improve the design of object-oriented systems », Springer Science & Business Media,‎
  • (en) Fabio Palomba, Gabriele Bavota, Rocco Oliveto et Andrea De Luzia, « Anti-Pattern Detection: Methods, Challenges and Open Issues », Advances in Computers, Chapter 4, vol. 95,‎
  • (en) Naouel Moha, Yann-Gaël Guéhéneuc, Laurence Duchien et Anne-Françoise Le Meur, « DECOR: A Method for the Specification and Detection of Code and Design Smells », IEEE Transactions on Software Engineering, vol. 36, no 1,‎ , p. 20-36 (ISSN 0098-5589, DOI 10.1109/TSE.2009.50)
  • (en) Marios Fokaefs, Nikolaos Tsantalis, Alexander Chatzigeorgiou et Jörg Sander, « Decomposing object-oriented class modules using an agglomerative clustering technique », IEEE International Conference on Software Maintenance,‎ , p. 93-101 (ISSN 1063-6773, DOI 10.1109/ICSM.2009.5306332)
  • (en) Cristina Marinescu, Radu Marinescu, Petru Florin Mihancea, Daniel Ratiu et Richard Wettel, « iplasma: An integrated platform for quality assessment of object-oriented design », International Conference on Software Maintenance,‎ , p. 77-80
  • (en) Nikolaos Tsantalis, Théodoros Chaikalis et Alexander Chatzigeorgiou, « JDeodorant: Identification and Removal of Type-Checking Bad Smells », IEEE European Conference on Software Maintenance and Reengineering,‎ , p. 329-331 (ISSN 1534-5351, DOI 10.1109/CSMR.2008.4493342)
  • (en) Emerson Murphy-Hill et Andrew P. Black, « Decomposing object-oriented class modules using an agglomerative clustering technique », IEEE International Symposium on Software Visualization,‎ , p. 5-14 (DOI 10.1145/1879211.1879216)
  • (en) Fabio Palomba, Rocco Oliveto, Gabriele Bavota, Andrea De Lucia, Massimiliano Di Penta et Denys Poshyvanyk, « Detecting Bad Smells in Source Code using Change History Information », IEEE International Conference on Automated Software Engineering,‎ , p. 268-278 (DOI 10.1109/ASE.2013.6693086)
  • (en) Fabio Palomba, Rocco Oliveto, Gabriele Bavota, Andrea De Lucia, Massimiliano Di Penta et Denys Poshyvanyk, « Mining Version Histories for Detecting Code Smells », IEEE Transactions on Software Engineering, vol. 41,‎ , p. 462-489 (DOI 10.1109/TSE.2014.2372760)
  • (en) Ankita Mann, Sandeep Dalal et Dhreej Chhillar, « An Effort to Improve Cohesion Metrics Using Inheritance », International Journal of Engineering and Advanced Technology, vol. 2,‎ (ISSN 2250-3005)
  • (en) Francesca Arcelli Fontana, Pietro Braione et Marco Zanoni, « Automatic detection of bad smells in code: An experimental assessment », Journal of Object Technology, vol. 11,‎
  • (en) Bartosz Walter et Pawel Martenka, « Looking for Patterns in Code Bad Smells Relations », IEEE International Conference on Software Testing, Verification and Validation Workshops,‎ , p. 465-466 (DOI 10.1109/ICSTW.2011.89)
  • (en) Nikolaos Tsantalis et Alexander Chatzigeorgiou, « Identification of Move Method Refactoring Opportunities », IEEE Transactions on Software Engineering, vol. 35,‎ , p. 347-367 (ISSN 0098-5589, DOI 10.1109/TSE.2009.1)
  • (en) M.V. Mäntylä, « Identification of Move Method Refactoring Opportunities », IEEE International Symposium on Empirical Software Engineering,‎ (DOI 10.1109/ISESE.2005.1541837)

Voir aussi[modifier | modifier le code]