Previous Up Next

3.3  Les <<systèmes de composition>>

Dans cette partie, nous allons explorer les différentes possibilités qui nous étaient offertes pour l'expression de la modularité de B par/dans un système de composition usuel. Par système de composition usuel, nous entendons un système permettant de mettre en oeuvre un principe de base du développement logiciel : la décomposition d'un problème en plusieurs sous-problèmes. Ce système de composition, s'il est intuitif, permettra une compréhension plus facile de la modularité de B. Il nous a semblé judicieux de s'intéresser aux systèmes utilisés dans les langages de programmation pour deux raisons. La première, parce qu'un tel choix répond a priori à l'objectif de simplicité et d'intuition. En effet, les langages de programmation sont en général connus des développeurs, ce qui facilitera leur compréhension du système de modules de B si un parallèle est possible avec des connaissances déjà acquises de leur part. La seconde raison qui nous a poussé vers des systèmes de composition proches des langages de programmation est l'objectif final du travail présenté dans ce mémoire : la génération de code. En choisissant une représentation proche des langages qui devront être finalement atteints par la phase de génération de code, nous faisons un premier pas vers le code sensé être généré en fin de chaîne.

Notons qu'il aurait été possible de s'intéresser également à des systèmes moins connus qui auraient tout aussi bien satisfait a priori notre objectif de simulation de la modularité de B. Mais ces systèmes, comme par exemple une évolution des systèmes à base de modules SML, les Mixin modules ([Ancona et al.98]), ne satisfont pas deux critères importants : d'une part, ils ne sont pas bien connus dans le monde du développement logiciel, et d'autre part, leur jeunesse fait de ces systèmes des systèmes en évolution; il faut donc attendre qu'ils atteignent un niveau de stabilité suffisant.

Dans les langages actuellement utilisés, nous trouvons trois grandes familles de systèmes de composition : les systèmes reposant sur l'utilisation des techniques objets (les langages de classes), ceux reposant sur l'utilisation des paquetages (à la Ada) et ceux reposant sur l'utilisation de modules/structures (à la ML). Chacun de ces systèmes a ses particularités, mais également des points communs. Nous allons dans la suite de cette section donner les arguments qui motiveront notre choix d'un de ces systèmes. Avant nous rappellerons brièvement (la littérature présentant les divers concepts étant nombreuse) la définition de ce que sont une classe, un paquetage et un module1. Cette présentation des concepts s'appuiera dans le cas des paquetages et des modules sur l'<<instanciation>> qui est faite de ces concepts pour les langages Ada et OCaml.

Classe
<<Une classe est un élément logiciel qui décrit un type abstrait de données et son implémentation totale ou partielle>> ([Meyer00]). Un type abstrait de données est une collection d'entités et un ensemble d'opérations manipulant ces entités. Une classe est à la fois un module (dans son sens le plus large : unité de décomposition) mais également un type. La création d'un objet du type d'une classe passe par une instanciation de cette classe.

Paquetage
Dans le manuel de référence Ada ([Ada94]), un paquetage est défini comme une unité de programme permettant la spécification de groupe d'entités logiquement reliées entre-elles. La définition d'un paquetage requiert la définition, d'une part, de sa spécification qui regroupe la définition des entités définies dans le paquetage (tout ou partie des entités) ainsi que de leur type, et d'autre part, du corps du paquetage qui définit concrètement les entités (variables, types, méthodes...).

Module
Un module est défini dans [Macqueen86] comme une collection nommée de déclarations dont le but est de définir un environnement. La notion de module dans les langages ML est très proche de la notion de paquetage. Comme pour les paquetages, la définition d'un module est divisée en deux, d'une part, l'interface du module qui spécifie ce qui est connu de l'extérieur, les entités et leur type, et d'autre part, le corps des entités constituant le module. La différence entre un module et les paquetages précédents réside dans la possibilité d'avoir plusieurs interfaces pour un même module, ce qui n'est pas possible pour les paquetages.

3.3.1  Les concepts de base

De la présentation que nous avons faite de la modularité de B, les concepts principaux qu'il semble intéressant de retrouver dans le système de composition sont :

L'encapsulation

L'encapsulation est un concept quasi universel dans les systèmes de composition. En effet, la possibilité de ne dévoiler qu'une partie d'une implantation, et donc d'en cacher une autre partie est une nécessité pour arriver à une certaine indépendance entre les différents modules. Dans les langages objets, trois catégories de visibilité se retrouvent en général : les entités peuvent être publiques, protégées, ou privées. Pour les langages utilisant les paquetages, les qualificatifs publique et privé se retrouvent également. Dans les langages de modules, l'utilisation des interfaces permet de dire si oui ou non telle entité est exportée. Cela correspond à la vision publique et privée des classes et des paquetages.

Les modes d'utilisation multiples

Un mode d'utilisation d'une même unité de composition consiste à spécifier quelles entités de cette unité de composition doivent être exportées. À chaque besoin sera associé un mode d'utilisation de l'unité de composition. Bien que relié à la notion précédente d'encapsulation, ce concept est différent. Ici, le but est de changer de vision sans pour autant changer de module. Cela correspond au besoin par exemple d'exporter toutes les opérations d'un module B lors d'une importation et de n'exporter que les opérations ne modifiant pas l'état du module dans le cas d'un accès par le lien Sees. Cette <<vision multiple>> d'un même module peut être obtenue par les systèmes à base de modules, par l'utilisation de plusieurs signatures pour le même module mais également pour certains langages de classes par le biais des interfaces (le langage Java par exemple supporte ces constructions).

La paramétrisation

La paramétrisation en B concerne comme nous l'avons déjà vu deux types de paramètres, des valeurs et des ensembles qui correspondent à des types. Autant le passage de valeurs ne pose pas de problèmes, autant le passage de types est plus problématique. En effet les types ne sont en général pas des citoyens de première classe dans les langages de programmation, ce qui fait qu'ils ne pourront pas être passés en paramètres comme les valeurs. Les solutions pour arriver à exprimer la paramétrisation existent pour les systèmes à base de modules et pour les systèmes à base de paquetages, pour les langages de classes, les solutions diffèrent suivant les langages (classes génériques en Eiffel, templates en C++). Pour les modules, il faut utiliser les constructions de foncteurs2 permettant de passer en paramètres des modules. Il est possible de définir dans ces modules passés en paramètres des types. Au niveau des paquetages, c'est la notion de paquetage générique qui sera utilisée. Les paquetages génériques correspondent exactement à ce que l'on cherche à faire ici : paramétriser les paquetages.

L'instanciation

L'instanciation correspond à la possibilité en B de reprendre le code d'un module. Le terme instanciation est un peu fort pour désigner ce processus de <<recopie>>. En effet, l'instanciation recouvre en général également le point précédent concernant la paramétrisation. Si les modules à instancier sont paramétrés, les mécanismes à utiliser sont les mêmes que précédemment. Par contre, si les modules B ne sont pas paramétrés, seuls les systèmes à base de classes fournissent la possibilité d'instancier plusieurs objets à partir d'une seule classe. Notons, qu'il est toujours possible de ramener un module non paramétré à un module paramétré dont les paramètres sont <<vides>>. L'usage de ce module ne sera possible qu'après instanciation de module par un module ne contenant aucun élément, cela permettra de simuler l'instanciation utilisée en B.

3.3.2  Choix du système

Critères de sélection

Dans la section précédente, nous avons abordé les aspects importants pour choisir parmi trois types de composition celui qui conviendrait le mieux à la simulation de la modularité de B. À ces quatre critères (dénotés par les lignes Encapsulation, Vision multiple, Paramétrisation et Instanciation multiple dans le tableau 3.9) correspondant directement au plongement des modules B dans un autre système et à l'aspect sociologique (dénoté par la ligne Compréhensible) que nous avons également abordé précédemment (le système retenu doit être intuitif), nous allons ajouter un critère supplémentaire, critère pragmatique visant à qualifier la difficulté à implanter un système simulant le système de modules de B (dénoté par la ligne Implantation fournie). Ce critère vise à évaluer la simplicité à implanter chacun des trois systèmes de composition.

Le tableau 3.9 reprend l'intégralité des critères de manière synthétique. Trois niveaux de qualification ont été retenu : +, ~ et - qui dans l'ordre évaluent l'adéquation du système suivant un critère d'une adéquation forte à une adéquation faible ou nulle. Le symbole ~ sera utilisé dans les cas où il est nécessaire d'utiliser un concept de manière détournée pour obtenir le résultat voulu (par exemple l'instanciation multiple pour les modules) ou lorsque ce concept n'est pas présent dans tous les langages majeurs de la catégorie (par exemple pour la paramétrisation des classes, qui existe en OCaml mais pas encore en Java).


  Critères Classe Module Package
Simulation du        
système de modules de B        
  Encapsulation + + +
  Vision multiple ~ + -
  Paramétrisation ~ + +
  Instanciation multiple + ~ ~
Aspects Pragmatiques        
  Implantation fournie - + -
  Système éprouvé + + +
Aspect sociologique        
  Compréhensible + + +

Table 3.9: Critères de sélection du système de <<composition>>


Système retenu

Il est impossible d'attribuer une valeur pour chaque niveau de qualification et pour chaque critère, tous les critères ayant une importance plus ou moins forte selon le système. Malgré cela, sur deux critères les systèmes à base de modules se montrent plus en adéquation avec B : la vision multiple et la facilité d'implantation du système. Le premier critère est une caractéristique primordiale du système de modules de B. Sans cette possibilité, bon nombre de spécifications actuellement existantes seraient rejetées. Le deuxième critère est quant à lui gage de sécurité : partir dans une voie balisée semble dans le cas d'un développement d'un système de modules prudent et sage. Pour ces raisons, nous avons choisi un système à base de modules ML et plus exactement le système à la Harper-Lillibridge-Leroy que nous allons présenter dans la section suivante.


Mise à jour : 30-1-2004 Heure : 17:47. Contact dorian.petit@univ-valenciennes.fr
Previous Up Next