Même si certains considèrent un composant logiciel comme un simple code binaire, nous donnerons au terme composant la définition informelle suivante qui rejoint celle donnée dans différents ouvrages et par différents auteurs : un composant est un module logiciel qui assure un service. Ce module logiciel est autonome et peut être installé sur différentes plates-formes. En vue de son utilisation ou de sa réutilisation, il exporte différents attributs ou méthodes sous forme d'interfaces. De plus, il possède des points d'entrée permettant sa configuration et est capable de s'auto décrire. L'OMG avec le modèle CCM, SUN avec les EJB ou Microsoft avec le modèle .NET répondent seulement en partie à cette définition. L'objectif affiché de la notion de composant est la réutilisation de modules logiciels, que ce soit lors de la construction de nouvelles applications par assemblage de composants existants, lors de l'intégration de nouveaux composants dans des logiciels existants. On emploie indifféremment les termes de composition ou d'assemblage.
Pour faciliter son assemblage avec d'autres composants, et donc sa réutilisation, nous considérons un composant, non pas comme un simple code binaire, mais comme un couple spécification-code, que l'on appellera composant contractualisable. En effet, la réutilisation et l'intégration d'un composant nécessitent la connaissance des propriétés de ce composant et de son comportement. Cette connaissance est en effet la base indispensable sans laquelle on ne peut fonder aucune évaluation objective de la qualité des assemblages dans lesquels intervient le composant. C'est pourquoi l'étape de spécification du composant est pour nous l'élément le plus important sur lequel se fonder pour la définition d'une application à base de composants. Lors de l'assemblage, c'est la spécification des propriétés du composant qu'on utilise pour définir les connecteurs entre composants, que nous appelons contrats d'assemblage. Par propriété d'un composant, nous entendons les services fournis par le composant sous forme d'interfaces, d'attributs, d'opérations, mais également les services requis par le composant, c'est-à-dire les dépendances aussi bien du point de vue d'autres composants que de l'environnement dans lequel va se déployer l'application.
Notre objectif est double. D'abord, nous proposons un modèle abstrait de composants, pour la description des propriétés (fournies et requises) des composants. Parallèlement, nous étudions la composition de l'application, et à expliciter un modèle formel d'assemblage de composants utilisant ces propriétés au sein de contrats.
Le modèle abstrait de composant fixe les hypothèses sur l'environnement dans lequel le composant va évoluer ainsi que les services rendus à cet environnement. Il décrit aussi de façon formelle les interactions possibles du composant en termes de modèles de coopération. Cette description vise à combler un manque : ces propriétés non fonctionnelles déduites de l'environnement sont en effet rarement exprimées, alors qu'elles interviennent fortement dans la spécification du comportement du composant. Il s'agit par exemple de propriétés liées au fait que l'application est répartie, s'exécute de façon concurrente ou encore est sécurisée. Un second problème s'exprime en terme de définition des modèles de coopération. Que ce soit dans les ADL ou dans les modèles CCM, les interfaces des composants sont décrites de manière syntaxique, avec très peu de sémantique associée. Les modèles de coopération proposés par les composants de type CCM tels que l'invocation de méthode ou l'action d'événement sont des modèles d'interaction de base. Une application à base de composants correspond à un ensemble d'entités qui réalisent collectivement un service au moyen d'interactions de communication. Lors de la spécification de l'assemblage des composants, il est donc nécessaire d'exprimer formellement les modèles de coopération utilisés, qui sont souvent des modèles plus riches qu'un modèle d'interaction entre un client et un serveur.
Pour répondre à ces problèmes, nous proposons de reposer notre modèle de composant abstrait sur un cadre formel fondé sur la notion de type abstrait coopératif. Les types abstraits coopératifs sont une extension des types abstraits classiques. En plus de définir formellement les aspects fonctionnels d'un objet, ils permettent la prise en compte de l'environnement dans lequel sera réalisé le module logiciel. Des pré- et post-conditions sur les opérations du composant définissent des contrats à respecter pour que celui-ci soit dit fiable. Ces pré- et post-opérations décrivent aussi bien des contraintes liées aux propriétés fonctionnelles que des contraintes de coopération du module logiciel avec son environnement, c'est-à-dire la structure d'accueil du module et les modules logiciels avec lesquels il doit coopérer pour réaliser le service défini.
Les outils utilisés pour la description formelle des comportements doivent donc permettre l'expression de l'environnement nécessaire au composant. Pour cela, des logiques modales, telles que les logiques épistémique et temporelle sont utilisées pour définir formellement l'évolution des données et l'expression du comportement dans un milieu réparti et concurrent.
Nous avons déjà mené une telle étude autour du typage abstrait coopératif dans les langages orientés objet. Nous proposons d'étendre cette étude à la notion de composant en enrichissant ce modèle. Une telle spécification devra comporter des contraintes (pré-conditions) et des résultats (post-conditions) du point de vue du composant client d'une opération, du composant serveur réalisant l'opération et des composants données, c'est-à-dire les paramètres impliqués dans l'opération.
Une conséquence de ce modèle de composant est qu'il permet de décrire de manière abstraite des composants dont les services ne sont pas tous co-localisés ; c'est-à-dire des composants répartis. On peut dès lors dissocier les besoins abstraits d'interconnexion entre les composants des contraintes concrètes de mises en oeuvre des appels des services à distance. Autrement dit, la mécanique de connexion des composants ne contient plus (nécessairement) la mécanique de communication à distance. On découple l'architecture logicielle de l'architecture matérielle en permettant à des composants répartis de rendre les services de communication.
Donc, contrairement à l'approche de type ADL (Architecture Description Language), qui masque à l'intérieur d'un connecteur de composant un mécanisme de communication - à titre indicatif l'ADL Unicon considère sept formes de connecteurs : DataAccess, FileIO, Pipe, PLBundler, ProcedureCall, RemoteProcCall, RTScheduler -, les connecteurs que nous proposons ne s'attachent qu'à la sémantique de la connexion, pas à sa mise en oeuvre qui est reportée dans les composants répartis. On reproche aux ADL le manque de sémantique commune des modèles et leurs objectifs de conception différents qui limitent les capacités d'interaction des langages et de leurs outils. Malgré des efforts comme le langage ACME en cours de développement qui a pour but de fournir un ADL pivot, il est difficile d'exprimer des interactions complexes, sortant du classique client-serveur, entre composants. En étudiant un modèle de composant contractualisable et réparti, nous limitons le rôle des connecteurs, toujours indispensables à l'assemblage, a un rôle fonctionnellement pauvre, mais potentiellement sémantiquement riche. Un outil d'assemblage doit assurer que les interfaces des composants sont compatibles, à la fois d'un point de vue fonctionnel (signature des services -- pré et post conditions), mais aussi non-fonctionnel (qualité de services, performance, etc.). Les interactions, élémentaires ou de haut niveau, sont intégrées dans des composants répartis.
Après avoir développé le modèle abstrait des composants contractualisables et des assemblages, il reste encore à rendre ces modèles utilisables concrètement par les architectes et intégrateurs de systèmes. Pour des raisons d'acceptabilité industrielle, le projet s'appuiera pour cela sur le langage UML. On tirera partie des possibilités d'extensions intrinsèques à UML au travers de la notion de profil, pour représenter en UML les concepts nécessaires aux notions de composants contractualisables et d'assemblages de composants définis précédemment. Ceci permettra de manipuler ces concepts directement depuis un atelier UML par des mécanismes de type « plug-in ».