1

yop,

Je me pose une question, parce que je n'ai jamais réussi à implémenter des messages entre objets de manière propre.

Disons qu'on ait une situation que je pense assez classique :
- un objet Dispatcher, qui reçoit les messages des différents objets et qui les redistribue
- une classe Listener, dont héritent les objets à qui d'autres vont s'adresse
- une classe Sender, dont héritent les objets qui vont vouloir s'adresser à d'autres
- une classe Message, définie très simplement, contenant SenderID, DestID
- des classes MessageX, dérivant de Message, pour y ajouter des données diverses en fonction des besoin.

Problème : si le Dispatcher peut recevoir un &MessageX et le retransmettre au destinataire sans connaitre son type précis (polymorphisme), il n'en va pas de même pour un Listener, qui va recevoir des messages de différents types.

Mon problème est là : comment le Listener peut détecter proprement le type du message pour le traiter correctement ?

Une solution naïve, que j'ai déjà écrite, consiste à attribuer un membre int Type à ma classe Message.
Le Listener lit alors ce pseudo-type, pour caster le Message dans le type souhaité, et ensuite l'utiliser.

Je sais pas pour vous, mais je trouve ça crade.
- d'abord parce que représenter un type à travers un int, pour moi c'est du bricolage
- ensuite parce que j'aime pas caster un objet dans tous les sens jusqu'à ce qu'il en sorte quelque chose d'intelligent
- enfin parce que ça oblige à définir une constate par message et par Listener, ce qui est source de lourdeur et d'erreur

Quelle serait alors une solution plus propre, permettant de retrouver le type d'un objet en fonction de ce qu'il est réellement, et non en fonction d'une variable qu'il contient ?

Merci d'avance pour vos éclaircissements. smile
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

2

Ah putain, je viens d'y penser... toujours après avoir écrit...

J'imagine que c'est aussi simple que "tu définis une méthode virtuelle pure void Receive (Message Msg) dans ta classe Listener, et tu la surcharges autant de fois que nécessaire dans tes Listener" ?

C'est ça ? T1 si c'est ça, je suis à la rue #trisick#

edit -> mhhh même pas sûr, le dispatcher va envoyer un &Message, pas un &MessageX... c'est ça ? Comment alors la bonne méthode sera appelée ? Ca marche aussi "dans ce sens" le polymorphismes ? Si c'est ça, j'ai les bases à revoir...
On fait comment sinon, on implémente quand même pas 50 méthodes pour le Sender, et 50000 dans le dispatcher pour ne faire que conserver le bon type de message passé ?? Je rate sûrement un truc évident...
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

3

Oui c'est une des façon les plus simple et courantes de procéder. C'est notamment ce qui se fait en Java.

Un autre méthode, consiste a faire un système de methode "Signaux"(sur l'emetteur) que l'on peut connecter à une methode "Slots"(sur le récepteur). Il y a diverses bibliothèques qui font ça. Je ne connait pas les détail de l'implémentation mais il me semble que ça s'appuie sur les callback comme en C, mais le modèle objet rend ça un peu plus complexe.
C'est notamment le mode de fonctionnement naturel de Qt, Par contre pour faire ça Qt oblige a recourir a un générateur de code (ou alors se farcir soi même du code très moche). Il me semble avoir vu des bibliothèque qui font ça de manière moins salle.
avatar

4

J'ai bien pensé à la méthode Qt qui va faire à la main les branchements entre objets, mais je veux m'en passer.

J'ai édité mon post précédent, ça marcherait en fait ? Si oui, comment ferait le dispatcher pour appeler la bonne fonction, alors qu'il ne connait qu'un type de message, celui de la classe de base ?
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !

5

Ah ben non, si la méthode void Receive (Message Msg) est virtuelle, le typage est alors dynamique, et l'appel de la bonne fonction sera fait au runtime.
C'est fou de pas encore avoir compris ça. couic
avatar
<<< Kernel Extremist©®™ >>>
Feel the power of (int16) !