• Aucun résultat trouvé

Différents mécanismes de contrôle de l’envoi de messages

Partie III : Une architecture de mise en œuvre 103

7.2 Réflexivité dans les langages à objets

7.2.3 Différents mécanismes de contrôle de l’envoi de messages

Il existe une multitude de façons de réaliser le contrôle de l’envoi de messages [Mae87a, Fer89, BKdR91, CM93, McA95]. Dans ce paragraphe, nous présentons les trois mécanismes permettant un contrôle de l’envoi de messages les plus souvent utilisés et les plus représentatifs.

Redéfinition de méthodes par sous-classage

Une solution souvent mise en œuvre pour contrôler les messages consiste à sous-classer la classe des objets à contrôler. Ce sous-classement permet de redéfinir les méthodes de la classe et ainsi rendre possible l’introduction d’un mécanisme de contrôle des messages.

L’un des inconvénient de cette approche est la définition d’un nombre non négligeable de classes dont le rôle se cantonne à prendre le contrôle des messages. En effet, ces classes générées et les méthodes redéfinies sont, bien souvent, vides d’une réelle sémantique.

Le contrôle de seulement certaines instances d’une classe implique, lorsque le langage le permet [Riv95, Riv96, Ser99], un changement de classe des instances contrôlées. Lorsqu’un tel changement n’est pas possible alors le sous-classement doit être réalisé soit par un transtypage, soit lors de la phase de conception. Dans ce dernier cas, le contrôle s’applique sur toutes les instances de la classe.

Le sous-classage permet également de contrôler les méthodes qui n’appartiennent pas à l’interface de l’objet contrôlé et outrepasse, dans une certaine mesure (grâce aux méthodes protectednotamment), le principe d’encapsulation de l’objet. Il n’offre, de plus, aucune abstraction du contrôle, ce dernier étant fortement lié à l’objet contrôlé puisque défini dans sa classe (ou, plus exactement l’une de ses sous-classes).

EXEMPLE. — La mise en œuvre de FLO[Duc97b] dans NEOCLASSTALK[Riv95] est basée sur cette solution. En effet, elle utilise les possibilités de changement dynamique de classe et de spécialisation du compilateur Smalltalk afin de modifier la sémantique des méthodes. Ainsi lorsqu’une instance doit être contrôlée, elle change de classe, sa nouvelle classe étant une sous-classe de la classe initiale permettant le contrôle des messages. Il est à noter que ce sous-classage est réalisé automatiquement par le système et non à la charge du programmeur.

Encapsulation et filtrage

Une autre solution consiste à encapsuler les objets devant être contrôlés. Cet encapsulation est ba-sée sur une substitution physique de l’identité de l’objet contrôlé par une capsule [Pas86], ou un filtre [ABV92]. Les messages envoyés à l’objet contrôlé sont en fait envoyés à la capsule ou au mécanisme de filtrage.

Les approches basées sur l’utilisation d’une capsule (figure 7.2b ci-dessous) définissent celle-ci comme étant un objet minimal [Bri89, PWG93] ne connaissant aucun message. Ainsi, le mécanisme de traitement des erreurs d’envoi de messages est invoqué (en Smalltalk, par exemple, il s’agit de la méthodedoesNotUnderstand:) et permet ainsi de contrôler les messages.

messages reçus messages envoyés filtres d'entrée méthodes filtres de sorties white white conditions "couche" interface objets internes variables d'instance objet filtré white white white white white

7.2a – Contrôle des messages par le biais du langage (notion de filtres)

anObject

une capsule

l'objet « contrôlé » référence initiale sur

l'objet « contrôlé »

nouvelle référence sur l'objet « contrôlé »

anObject

avant le contrôle après le contrôle

7.2b – Contrôle des messages par le biais d’un objet « capsule »

FIG. 7.2 –Contrôle des messages par des capsules ou des filtres

Dans le cas des approches utilisant des filtres, les messages envoyés à un objet contrôlé sont intercep-tés et filtrés (figure 7.2a ci-dessus). Le contrôle des messages est réalisée lors du filtrage. Par exemple, dans le modèle des filtres de composition [AW+

93], chaque filtre spécifie comment un message reçu par le mécanisme de filtrage doit être transmis au filtre suivant ou à l’objet destinataire du message.

Cette solution implique, notamment dans le cas des approches avec capsule, un changement dyna-mique des références des objets contrôlés. De plus, le sur-coût apporté par le contrôle est non négligeable (puisqu’il implique une double recherche du message, une première fois dans l’objet capsule ou à travers les filtres, et une seconde fois dans l’objet encapsulé).

Ces notions de filtrage ou d’objet capsule, ne permettent pas, en raison du concept d’encapsulation du modèle à objets, de contrôler les messages n’appartenant pas à l’interface des objets contrôlés. En effet, le contrôle est défini hors de l’objet contrôlé.

Ceci implique, et ce n’est pas anodin, que seuls les messages émis depuis l’extérieur de l’objet peuvent être contrôlés [PWG93]. Enfin, ces approches n’offrent aucune abstraction du contrôle en ne fournissant pas de véritable distinction entre l’objet contrôlé et le contrôle lui-même (puisque les deux sont très fortement liés).

Utilisation de la réflexivité et des métaobjets

D’autres approches permettent un contrôle des messages en se basant sur les concepts définis par P. MAESdans [Mae87b, Mae88]. Parmi ces concepts, P. MAESintroduit le fait qu’un objet est associé à un métaobjet qui contient toutes les informations réflexives, dont notamment la manière dont l’objet réagit aux messages. Ainsi, il est possible d’associer aux objets, dont certains messages doivent être contrôlés un métaobjet spécifique qui définit ce contrôle.

Dans les langages à objets, le mécanisme d’envoi de messages est l’unique moyen offert aux objets pour communiquer entre eux. Ainsi, le contrôle de l’envoi de messages est donc l’une des préoccupa-tions majeures de tous les systèmes réflexifs offrant un support à la réflexion comportementale [MC93]. Or, l’exécution d’un message fait partie intégrante du mécanisme d’envoi de messages [McA95]. EXEMPLE. — La première version d’Open C++ [Chi93] propose une abstraction de l’envoi de messages en associant un

métaobjet aux objets dont le comportement doit être contrôlé. Lors de l’invocation d’une méthode réflexive sur l’objet contrôlé la méthodeMeta_MethodCalldu métaobjet est exécutée. C’est en redéfinissant cette méthode que le programmeur peut contrôler les messages.

Il est à noter que certaines approches

asso-send: M ‚accept: M ƒqueue: M …next „receive M ‡execute: method †methodFor: M A B Send Accept Queue Receive Protocol Execution

FIG. 7.3 –Contrôle des messages par le biais de mé-taobjets (ici ceux de CODA)

cient plusieurs métaobjets pour le contrôle des messages (figure 7.3 ci-contre), chaque métaob-jet réalisant une étape du mécanisme d’envoi de messages. De plus, certaines approches, comme par exemple le langage à prototypes MOOSTRAP [MC93], associe à chaque objet (y compris les métaobjets) un métaobjet. Par conséquent, le mé-canisme de contrôle de l’envoi de messages dé-finit par ces approches peut s’avérer très coûteux aussi bien en temps d’exécution qu’en place mé-moire.

EXEMPLE. — Le MOP de CODA [McA95] est un MOP spécialisé dans l’abstraction de la communication entre objets. Il pro-pose en effet sept méta-composants (figure 7.3) permettant de contrôler très finement le mécanisme d’envoi de messages (de l’envoi proprement dit jusqu’à l’exécution du message par l’objet destinataire).

Support du contrôle de l’envoi de messages dans les langages réflexifs

Parmi les premiers langages à avoir introduit le contrôle de l’envoi de messages, on peut citer Small-talk. À l’aide de la méthodedoesNotUnderstand:[GR83], il permet de définir la sémantique associée à la réception d’un message non connu. Ainsi, en substituant un objet minimal sans méthodes (provoquant par conséquent un appel à la méthode doesNotUnderstand:à chaque invocation), il est possible de définir de nouvelles sémantiques à l’envoi de messages (par exemple l’invocation distante [McC87]). L’article [Duc97a] décrit d’autres techniques de contrôle de l’envoi de messages en Smalltalk.

Quant à lui, le langage 3-KRS [Mae87a] fournit à chaque objet un métaobjet gérant l’intégralité des concepts du modèle (héritage, envoi de messages, etc.). Ainsi, un message reçu par un objet est automatiquement transmis par ce dernier à son métaobjet. De ce fait, la modification des métaobjets permet de définir de nouvelles sémantiques non envisagées à l’origine.

Une technique similaire est proposée par la première version d’Open C++ [CM93, Chi93] qui offre un métaobjet de gestion des envois de messages. Celui-ci réifie l’appel d’une méthode sur un objet et permet d’appliquer un traitement spécifique sur cet appel (par exemple modifier les paramètres, etc.). La version 2 d’Open C++ [Chi95] permet, quant à elle, de modifier l’arbre de syntaxe abstraite d’un pro-gramme C++. Ainsi, elle permet également de modifier le mécanisme d’envoi de messages. Cependant, aucun métaobjet gérant les envois de messages n’est disponible2. L’extension de l’envoi de messages s’effectue donc par la modification du code C++ réalisant l’envoi de messages.

CODA [McA95] utilise, lui aussi, la notion de métaobjet pour permettre le contrôle de l’envoi de messages (figure 7.3). Cependant, ce contrôle n’est pas encapsulé par un unique métaobjet (comme cela est le cas avec les langages ci-dessus) mais par un ensemble de sept métaobjets. Ils disposent tous d’un rôle particulier dans un environnement concurrent et distribué. CODA offre donc une granularité très fine du contrôle de l’envoi de messages contre une complexité accrue de mise en œuvre.

2. En effet, la gestion de l’envoi de messages a lieu durant l’exécution du programme, or le MOP d’Open C++ v2 s’applique durant la phase de compilation.

En se concentrant principalement sur la communication entre objets, CODA propose un protocole dont le pouvoir d’expression est beaucoup plus riche que la plupart des MOP. Il permet de distinguer clairement chacune des étapes de la communication entre objets. Ainsi, il entre en jeu dès l’émission des messages, et pas seulement à leur réception comme cela est le cas dans les autres approches. De plus, le MOP de CODA n’est lié à aucun langage à objets spécifique et peut être perçu comme un modèle de MOP pour le contrôle de l’envoi de messages.