Qu’est-ce que la haute cohésion et comment l’utiliser?

J’apprends la programmation informatique et à plusieurs endroits, je suis tombé sur le concept de cohésion et je comprends qu’il est souhaitable qu’un logiciel ait une “grande cohésion”, mais que signifie-t-il? Je suis un programmeur Java, C et Python qui apprend le C ++ à partir du livre C ++ Primer qui mentionne la cohésion sans l’avoir dans l’index. Pourriez-vous nous indiquer quelques liens sur ce sujet? Je n’ai pas trouvé la page wikipedia sur la cohésion informatique informative car elle dit simplement que c’est une mesure qualitative et ne donne pas d’exemples de code réels.

La grande cohésion est quand vous avez une classe qui fait un travail bien défini. La faible cohésion, c’est quand une classe fait beaucoup d’emplois qui n’ont pas grand chose en commun.

Prenons cet exemple:

Vous avez une classe qui ajoute deux nombres, mais la même classe crée une fenêtre affichant le résultat. C’est une classe peu cohérente car la fenêtre et l’opération d’ajout n’ont pas beaucoup en commun. La fenêtre est la partie visuelle du programme et la fonction d’ajout est la logique derrière.

Pour créer une solution hautement cohésive, vous devez créer une classe Window et une classe Sum. La fenêtre appelle la méthode de Sum pour obtenir le résultat et l’afficher. De cette façon, vous développerez séparément la logique et l’interface graphique de votre application.

Une explication de ce que dit le code complet de Steve McConnell:

La cohésion se réfère à la proximité de toutes les routines d’une classe ou de tout le code dans une routine. Les classes qui contiennent des fonctionnalités fortement liées sont décrites comme ayant une forte cohésion, et l’objective heuristique est de rendre la cohésion aussi forte que possible. La cohésion est un outil utile pour gérer la complexité, car plus le code dans une classe prend en charge un objective central, plus votre cerveau peut mémoriser tout ce que le code fait.

Un moyen d’y parvenir grâce au code propre d’oncle Bob:

Les classes doivent avoir un petit nombre de variables d’instance . Chacune des méthodes d’une classe doit manipuler une ou plusieurs de ces variables. En général, plus une méthode manipule de variables, plus cette méthode est cohérente avec sa classe. Une classe dans laquelle chaque variable est utilisée par chaque méthode est cohésive au maximum.

En général, il n’est ni souhaitable ni possible de créer des classes aussi cohésives; d’autre part, nous aimerions que la cohésion soit élevée. Lorsque la cohésion est élevée, cela signifie que les méthodes et les variables de la classe sont co-dépendantes et se regroupent en un tout logique.

La notion de cohésion est fortement liée à la notion de couplage; De plus, il existe un principe basé sur l’heuristique de la haute cohésion, appelée principe de la responsabilité unique (le S de SOLID).

La haute cohésion est un concept d’ingénierie logicielle. Fondamentalement, il est dit qu’une classe ne devrait faire que ce qu’elle est censée faire et le fait pleinement. Ne le surchargez pas avec des fonctions qu’il n’est pas censé faire, et tout ce qui lui est directement lié ne devrait pas non plus apparaître dans le code d’une autre classe.

L’exemple est assez subjectif, puisque nous devons également considérer l’échelle. Un programme simple ne devrait pas être trop modularisé ou il serait fragmenté; alors qu’un programme complexe peut nécessiter plus de niveaux d’abstractions pour gérer la complexité.

ex. classe de messagerie. Il doit contenir des membres de données à partir de, cc, bcc, subject, body et peut contenir ces méthodes saveAsDraft (), send (), discardDraft (). Mais login () ne doit pas être présent, car il existe un certain nombre de protocoles de messagerie et doit être implémenté séparément.

La cohésion est généralement mesurée à l’aide de l’un des parameters LCOM (manque de cohésion), la mésortingque originale de LCOM étant venue de Chidamber et de Kemerer. Voir par exemple: http://www.computing.dcu.ie/~renaat/ca421/LCOM.html

Un exemple plus concret: si une classe a par exemple un champ privé et trois méthodes; Lorsque les trois méthodes utilisent ce champ pour effectuer une opération, la classe est très cohérente.

Pseudo-code d’une classe cohérente:

class FooBar { private SomeObject _bla = new SomeObject(); public void FirstMethod() { _bla.FirstCall(); } public void SecondMethod() { _bla.SecondCall(); } public void ThirdMethod() { _bla.ThirdCall(); } } 

Si une classe a par exemple trois champs privés et trois méthodes; Lorsque les trois méthodes utilisent un seul des trois champs, la classe est peu cohérente.

Pseudo-code d’une classe peu cohésive:

 class FooBar { private SomeObject _bla = new SomeObject(); private SomeObject _foo = new SomeObject(); private SomeObject _bar = new SomeObject(); public void FirstMethod() { _bla.Call(); } public void SecondMethod() { _foo.Call(); } public void ThirdMethod() { _bar.Call(); } } 

Le principe de la «classe qui fait une chose» est le principe de la responsabilité unique qui provient de Robert C. Martin et qui est l’un des principes de SOLID . Le principe prescrit qu’une classe ne devrait avoir qu’une seule raison de changer.

Rester proche du principe de la responsabilité unique pourrait éventuellement aboutir à un code plus cohérent, mais à mon avis, ce sont deux choses différentes.

Ceci est un exemple de faible cohésion:

 class Calculator { public static void main(Ssortingng args[]) { //calculating sum here result = a + b; //calculating difference here result = a - b; //same for multiplication and division } } 

Mais la grande cohésion implique que les fonctions dans les classes font ce qu’elles sont censées faire (comme elles sont nommées). Et pas une fonction qui fait le travail d’une autre fonction. Ainsi, ce qui suit peut être un exemple de forte cohésion:

 class Calculator { public static void main(Ssortingng args[]) { Calculator myObj = new Calculator(); System.out.println(myObj.SumOfTwoNumbers(5,7)); } public int SumOfTwoNumbers(int a, int b) { return (a+b); } //similarly for other operations } 

La cohésion signifie qu’une classe ou une méthode ne fait qu’un travail défini. le nom de la méthode ou de la classe doit également être explicite. Par exemple, si vous écrivez une calculasortingce, vous devez nommer la classe “calculasortingce” et non “asdfghj”. Vous devriez également envisager de créer une méthode pour chaque tâche, par exemple subtract () add (), etc. Le programmeur qui pourrait utiliser votre programme à l’avenir sait exactement ce que font vos méthodes. un bon nommage peut réduire les efforts de commentaires

un principe est aussi SEC – ne te répète pas

Une manière générale de penser au principe de cohésion est que vous devez localiser un code avec d’autres codes qui en dépendent ou dont il dépend. La cohésion peut et doit être appliquée à des niveaux de composition supérieurs au niveau de la classe. Par exemple, un package ou un espace de noms devrait idéalement contenir des classes liées à un thème commun et qui sont plus fortement interdépendantes que dépendantes d’autres packages / espaces de noms. Ie garder des dépendances locales.

L’ article de MSDN à ce sujet est probablement plus informatif que Wikipedia dans ce cas.

Le terme de cohésion était à l’origine utilisé pour décrire les modules du code source en tant que mesure qualitative de la manière dont le code source du module était lié l’un à l’autre. L’idée de cohésion est utilisée dans une variété de domaines. Par exemple, un groupe de personnes comme une unité militaire peut être cohérent, ce qui signifie que les membres de l’unité travaillent ensemble vers un objective commun.

L’essence de la cohésion du code source réside dans le fait que le code source d’un module fonctionne ensemble pour atteindre un objective commun bien défini. La quantité minimale de code source nécessaire pour créer les sorties du module se trouve dans le module et pas plus. L’interface est bien définie et les entrées passent par l’interface et les sorties sont renvoyées par l’interface. Il n’y a pas d’effets secondaires et l’accent est mis sur le minimalisme.

Un avantage des modules fonctionnellement cohérents est que le développement et l’automatisation des tests unitaires sont simples. En fait, il est facile de créer un ensemble complet de tests unitaires exhaustifs pour le module.

Un module peut être une classe dans un langage orienté object ou une fonction dans un langage fonctionnel ou un langage non orienté object tel que C. Une grande partie du travail original dans ce domaine de mesure de la cohésion impliquait principalement de travailler avec des programmes COBOL chez IBM. 1970 alors la cohésion n’est pas seulement un concept orienté object.

L’intention originelle de la recherche à partir de laquelle le concept de cohésion et le concept associé de couplage provenaient de la recherche était de savoir où se situaient les caractéristiques des programmes faciles à comprendre, à maintenir et à étendre. L’objective était de pouvoir apprendre les meilleures pratiques de programmation, codifier ces meilleures pratiques, puis enseigner les pratiques à d’autres programmeurs.

Le but des bons programmeurs est d’écrire du code source dont la cohésion est la plus élevée possible compte tenu de l’environnement et du problème à résoudre. Cela implique que dans une grande application, certaines parties du corps du code source varieront des autres parties quant au niveau de cohésion du code source dans ce module ou cette classe. La cohésion temporelle ou séquentielle due au problème que vous tentez de résoudre est à peu près le meilleur.

Le meilleur niveau de cohésion est la cohésion fonctionnelle. Un module à cohésion fonctionnelle est similaire à une fonction mathématique en ce sens que vous fournissez un ensemble d’entrées et que vous obtenez une sortie spécifique. Un module vraiment fonctionnel n’aura pas d’effets secondaires en plus de la sortie et ne maintiendra aucun état. Il aura plutôt une interface bien définie qui encapsule les fonctionnalités du module sans exposer aucun des composants internes du module et la personne utilisant le module fournira un ensemble particulier d’entrées et obtiendra en retour une sortie particulière. Un module vraiment fonctionnel devrait également être sécurisé.

De nombreuses bibliothèques de langage de programmation contiennent un certain nombre d’exemples de modules fonctionnels, qu’il s’agisse de classes, de modèles ou de fonctions. Les exemples cohésifs les plus fonctionnels seraient des fonctions mathématiques telles que le péché, le cosinus, la racine carrée, etc.

D’autres fonctions peuvent avoir des effets secondaires ou maintenir un état quelconque, ce qui complique l’utilisation de ces fonctions.

Par exemple, une fonction qui émet une exception ou définit une variable d’erreur globale ( errno in C) ou doit être utilisée dans une séquence (la fonction strtok() est un exemple de la bibliothèque C standard lorsqu’elle maintient un état interne) ou fournit une pointeur qui doit ensuite être géré ou envoie un journal à un utilitaire de journal sont tous des exemples d’une fonction qui n’est plus une cohésion fonctionnelle.

J’ai lu l’ouvrage original de Yourdon et Constantine, Structured Programming, où je suis tombé sur l’idée de la cohésion dans les années 1980 et le livre de Meilir Page-Jones intitulé Practical Guide to Structured Systems Design. à la fois couplage et cohésion. Le livre Yourdon et Constantine semble un peu plus académique. Le livre de Steve McConnell, Code Complete, est assez bon et pratique et l’édition révisée a beaucoup à dire sur les bonnes pratiques de programmation.