Tolérance aux fautes sur CORBA par protocole à méta objets et langages réflexifs
Réflexivité et protocoles à méta objets
De nombreuses classes d’applications nécessitent des propriétés totalement indépendantes de leurs fonctionnalités, comme la persistance ou la sécurité. On qualifie parfois ces propriétés de non fonctionnelles car elles sont orthogonales à l’application. Des outils issus du modèle orienté-objet ont été développés pour traiter certains mécanismes orthogonaux récurrents comme les «fabriques abstraites d’objets» ou encore les «adaptateurs». Ces outils sont des modèles de conception qui utilisent la délégation et l’héritage afin d’augmenter leur réutilisabilité et leur généralité ; on appelle ces outils les «Design Patterns» [Gamma et al. 1995]. Une autre solution pratique pour l’implémentation de mécanismes orthogonaux à l’application est l’utilisation de la réflexivité [Stroud 1993], particulièrement sous la forme de protocole à méta objets. En effet, ces notions ont prouvé qu’elles permettent non seulement d’implémenter ces mécanismes d’une façon élégante et efficace mais surtout qu’elles fournissent une grande flexibilité, tout en étant transparentes pour l’utilisateur.
Réflexivité
La réflexivité est la propriété d’un système qui est capable de raisonner à propos de lui-même [Maes et Nardi 1988]. Cette définition élémentaire, qui peut paraître obscure, introduit la notion de moyens d’analyse, de modification ou d’extension a posteriori du comportement initial du système. Ce concept est à la base même de celui de méta objets, nous en donnons ici une définition.
Définition
Le terme réflexif est issu de la philosophie. Il est défini comme suit [Larousse 1972] : Qui concerne la conscience se connaissant elle-même : la méthode réflexive remonte des conditions de la pensée à l’unité de la pensée. Le terme de réflexivité a, quant à lui, été introduit en logique pour désigner un moyen d’étendre les théories. Ensuite, il a été utilisé pour exprimer la relation entre la théorie et la méta-théorie dans les systèmes de raisonnement logique. Plus récemment, la réflexivité a été adoptée comme un outil puissant et général des langages de programmation. On peut en donner la définition suivante [Maes et Nardi 1988] : Un système informatique est dit réflexif lorsqu’il fait lui-même partie de son propre domaine. Plus précisément cela implique que (i) le système a une représentation interne de lui-même, et (ii) le système alterne parfois entre calcul «normal» à propos de son domaine externe et calcul «réflexif» à propos de lui-même. Ces définitions nécessitent des éclaircissements. On peut dire que le système réflexif contient une auto-représentation qui décrit la connaissance qu’il a de lui-même.
Le système et son auto-représentation sont liés de manière causale : si l’un d’entre eux est modifié, l’autre l’est en conséquence. Un système réflexif peut donc s’auto-modifier en modifiant son auto-représentation, et son auto-représentation reste toujours cohérente avec son état réel. On appelle niveau de base le système lui même. Le méta-niveau contient le modèle du niveau de base (l’auto-représentation du système) qu’il peut interpréter et modifier. Ces deux notions, illustrées par la figure 6, sont liées par deux processus d’interaction, la réification qui s’opère du niveau de base vers le méta-niveau lorsque le premier subit une modification devant être reflétée dans le second, et l’intercession, qui va du méta-niveau vers le niveau de base lorsqu’une modification du premier doit s’opérer sur le dernier. Figure 6 – Réflexivité : définitions niveau de base méta-niveau réification intercession 18 Chapitre I Systèmes à objets, réflexivité et protocoles à métaobjets
Niveaux multiples de réflexivité
Selon le système considéré, les propriétés apportées par la réflexivité peuvent être très différentes. Nous donnons ici plusieurs exemples de réflexivité afin d’illustrer les possibilités qu’offre cette notion dans le cadre général des systèmes informatiques.
Réflexivité du langage
Historiquement, la réflexivité a été introduite pour modéliser la représentation de la connaissance dans des systèmes d’intelligence artificielle, systèmes experts, etc. Ces différents systèmes raisonnent à partir d’une base de connaissance qu’ils peuvent enrichir de leurs propres déductions. On peut voir un tel système comme un programme interprété qui s’auto-modifie au fur et à mesure qu’il génère de nouvelles règles. De nos jours, on peut classifier les langages de programmation en deux grandes catégories, les langages qui sont interprétés et ceux qui sont compilés. En effet cette différence est très importante en ce qui concerne la réflexivité. Un programme écrit dans un langage interprété, comme en LISP, en Smalltalk ou encore en Java, est interprété par un programme spécifique appelé interpréteur. L’interpréteur évalue à l’exécution le programme source et exécute, en fonction de cette évaluation, son propre code machine. La réflexivité d’un tel langage permet donc au programme de s’auto-modifier à l’exécution permettant une très grande adaptabilité du programme à son environnement.
Ces propriétés sont néanmoins obtenues au prix d’une certaine complexité. Certains de ces langages, comme Perl [Dominus 1998], poussent cette notion de réflexivité très loin : l’interpréteur est considéré comme un programme à part entière qui peut lui-aussi être modifié par le programme qu’il interprète. Cette approche de la réflexivité hérite tout autant des avantages que des inconvénients des langages interprétés. La méthode est très flexible car tout est contrôlable à l’exécution du programme, en revanche cette dynamicité se paye en termes de performances; en effet, l’interprétation d’un programme est très coûteuse en temps processeur. A l’inverse des langages interprétés, les programmes écrits dans un langage compilé sont traduits en langage machine avant leur exécution. Le programme qui effectue cette traduction est appelé compilateur. De même que les langages interprétés réflexifs s’appuient sur un interpréteur réflexif, les langages compilés réflexifs s’appuient sur un compilateur réflexif.
Celui-ci permet au méta-niveau de contrôler la façon dont le programme est compilé. Le méta-niveau peut alors être vu comme un ensemble de règles de traduction du programme source. On parle alors de compilateur ouvert, car le compilateur est programmable ; le méta-niveau est appelé méta-programme, il est responsable de la compilation du niveau de base, le programme source. La plupart des compilateurs réflexifs sont basés sur des langages orientés-objet, nous les détaillerons donc dans la section I.3.2..
Introduction générale |