• Aucun résultat trouvé

Chapitre 5 EVOLUTION DU PROJET EM2

5.3. l Implantation du noyau

6.1.3 La complexité

Un indicateur significatif de la bonne qualité du logiciel est sa faible complexité. Des concepts, comme la programmation structurée, la modularité et l'abstraction ont permis d'aider à maîtriser la complexité que présente un logiciel en le décomposant en petites parties indépendantes et en le structurant.

La complexité réelle d'un projet est fixée dès l'énoncé du problème, mais la complexité apparente de sa réalisation peut varier considérablement puisqu'elle se compose de la complexité réelle augmentée par la complexité de l'implantation. Notre objectif est de mesurer et de diminuer au maximum la complexité de l'implantation. Un obstacle vient du fait qu'il est difficile de la distinguer de la complexité propre au projet.

La complexité apparente se divise en deux types de complexité: la complexité physique et la complexité psychologique [Cur 81]. La complexité physique consiste en une évaluation quantitative des caractéristiques du code (par exemple, le nombre d'appels à des procédures ou le nombre d'instructions conditionnelles). La complexité psychologique est liée à l'effort de compréhension de la structure et du fonctionnement du logiciel.

Nous avons vu qu'il y a plusieurs types de complexité d'un logiciel:

la complexité physique et la complexité psychologique. Selon Shneiderman [Shn 80], la complexité physique se décompose en une complexité logique et une complexité structurelle.

Complexité logique

La complexité logique comprend les caractéristiques qui font que la preuve qu'un programme est correct devient difficile à effectuer, c'est-à-dire le nombre et la longueur des chemins suivis par les données d'un logiciel. Par exemple, le nombre de lignes du logiciel [Hal 77) ou le nombre d'instructions conditionnelles [Mec 76) sont des mesures utiles car elles sont simples et facilement automatisables. Elles pem1ettent, en outre, d'avoir une assez bonne estimation de la complexité. Elles ont eu, d'ailleurs, un assez grand succès. Ce type de complexité est un bon indicateur du coût d'un logiciel.

Complexité structurelle

La complexité structurelle consiste à évaluer la complexité de la structure, en termes de modules, d'un logiciel. Le nombre et la nature des modules ainsi que le nombre et la nature des liens qui les relient sont les critères de basé. Myers [Mye 78) a défini les concepts de couplage et de cohésion pour l'évaluation de ces critères. Une approche complémentaire [Tur 80), encore peu répandue, consiste à évaluer la complexité de l'ensemble des relations entre modules. Le couplage caractérise uniquement les liens entre deux modules: il ne donne pas d'information sur l'allure générale de la structure de ces modules.

Dans ce travail, nous allons nous intéresser plus particulièrement à ce type de complexité pour lequel nous avons développé des métriques.

Complexité psychologique

La complexité psychologique est liée à la compréhension du logiciel. Les critères de base sont, principalement; le nombre et la qualité des commentaires et la qualité des mnémoniques utilisés pour caractériser les différents objets [She 78), [Shn 77] et [Woo 81). Certain de ces critères sont difficilement automatisables, ·car ils sont basés sur la sémantique contenue dans le logiciel.

Par exemple, l'approche de Halstead consiste à dériver une mesure de la complexité psychologique à partir de diverses opérations de dénombrement effectuées sur le code et de considérations psychologiques.

6.2 QUALITÉ ET MODULARITÉ 6.2.1 Définition

L'avènement de la modularité à travers des langages réellement modulaires tels que ADA ou MODULA-2 a permis d'introduire de nouveaux procédés de développemenL La conception modulaire [Boo 83) en est un des plus importants. Le concept de modularité a introduit un nouveau niveau d'abstraction entre le niveau code et le niveau projet.

Plus récemment est apparu le concept d'objet qui définit encore un nouveau niveau d'abstraction qui se situe entre le niveau module et le niveau code. Un objet est une entité ayant des caractéristiques qui lui sont propres, mais transmissibles à un nouvel objet. Dans notre travail, nous considérons toujours la notion d'objet au sens défini dans les chapitres

précédents, qui est un sens relativement faible par rapport au sens des langages orientés objet tel SMALLTALK [Gol 83].

Il y a plusieurs définitions du terme module. Selon les cas, un module peut être une sous-routine FORTRAN, un package ADA ou la tâche de programmation assignée à un programmeur particulier. Toutes ces interprétations sont correctes, dans le sens que ces modules définissent un niveau conceptuel en présentant une certaine abstraction et en implantant les détails de cette abstraction. La modularité est un critère important dans la conception d'un système.

Cette notion étendue de module est propre à ce chapitre; dans les chapitres suivants nous reprendrons la notion au sens fort du terme, c'est-à-dire celle définie dans les langages modulaires tels MODULA-2 ou ADA . Mais cet élargissement de la notion est important pour comprendre les différents critères d'évaluation qui ont été défini jusqu'à maintenant.

Ainsi, les critères de cohésion et de couplage, que nous décrirons dans les paragraphes suivants, permettent de caractériser les modules, où le terme module doit être pris dans un sens très large.

La modularité est fortement liée à la complexité qu'elle permet de mieux maîtriser. En effet, la modularité permet de diviser un logiciel en petites unités et, donc, de répartir la complexité dans ces unités, tout en induisant un nouveau type de complexité entre ces unités.

Liens entre modules

Les modules sont des unités logiques qui peuvent s'utiliser entre elles. Ainsi, un module peut~tiliser les fonctionnalités d'un ou de plusieurs autres modules. Les liens entre modules sont donc orientés.

On dit qu'un module B est subordonné à un module A si le module B est appelé par le module A ou par un module subordonné à A. Le module Best directement subordonné à A s'il est directement appelé par le module A (figure 6.2).

Un module peut être appelé par plusieurs modules ou peut appeler lui-même plusieurs autres modules. Le fan-in d'un module décrit le nombre de modules qui l'appelle, alors que le fan-out correspond au nombre de modules qu'il appelle.

Ces différentes notions sont illustrées sur la figure 6.2. Si l'on regarde l'ensemble des modules d'un logiciel et de leurs dépendances, on constate qu'il représente une structure hiérarchique qui se caractérise, entre autre, par le nombre de niveaux différents: la profondeur et par le nombre de modules sur un même niveau: la largeur. Le nombre de

niveaux est une valeur fixe d'un logiciel, alors que la largeur peut prendre des valeurs différentes car le niveau d'un module peut varier.

p 0 f 0 n d e u

A

largeur

Le module B est directement subordonné au module A Le module C est indirectement subordonné au module A

niveau O

niveau 1

niveau 2

niveau 3

Figure 6.2 : Différentes caractéristiques des modules selon [Gen 86]

Description d'un module

Une bonne description d'un module doit tenir compte de la fonction du modn le, <le sa logique et de son contexte. La fonction décrit ce que fait le module, sa logique décrit comment le module réalise cette fonction, et son contexte présente dans quelles conditions et de quelle manière on peut l'utiliser.

Taille des modules

La décomposition en modules apporte une aide conséquente pour la conception d'un logiciel, mais il y a toujours le problème de savoir ce que doit contenir un module, et quelle doit être sa taille. Un projet a une taille fixe, mais le nombre de modules qui le composent peut varier suivant ce que l'on décide de mettre dans chacun d'eux. Ainsi, un projet super-modularisé a un grand nombre de petits modules peu complexes, mais les liens entre ces modules induisent une structure modulaire très complexe.

A l'opposé, un projet peu-modularisé a un petit nombre de modules. Dans ce cas, la structure modulaire est simple car elle ne contient que peu de

liens, et la complexité inter-modulaire est faible, mais la complexité intra-modulaire de chaque module est élevée. Il faut donc trouver un compromis entre le nombre et la taille des modules (figure 6.3). Une étude, effectuée par Woodfield, Dunsmore et Shen [Woo 81], montre l'impact de différents types de modularisation (monolithique, fonctionnelle, super-modularisation et types abstraits) sur la compréhension d'un programme.

Le facteur taille d'un module vient, en général, après les autres facteurs. Mais on peut dire qu'une règle communément admise est que la taille d'un module doit être environ d'une cinquantaine de lignes [You 75].

Un objectif important lors de la conception est de décomposer et structurer le logiciel en un certain nombre d'éléments tout en optimisant le nombre et la complexité des interconnexions. Stevens, Constantine et Myers [Ste 74] ont introduit les concepts de couplage et de cohésion pour caractériser les modules et leurs interconnexions. Ces deux concepts ne sont pas indépendants, certains types de cohésion entrament certains types de couplage (voir chapitre 8).

Complexité

(coût) Complexité

totale

Nombre optimal de modules

Complexité inter-modulaire

Complexité intra-modulaire

Nombre de modules

Figure 6.3: La complexité en fonction de la taille et du nombre de modules d'un projet