J'ai créé deux classes abstraites Subject et Observer qui définissent une interface de modèle Observer classique. Je dérive d'eux pour implémenter le modèle Observer. Un observateur pourrait ressembler à ceci:
void MyClass::Update(Subject *subject)
{
if(subject == myService_)
{
DoSomething();
}
else if(subject == myOtherService_)
{
DoSomethingElse();
}
}
C'est bien et ça me dit qui a changé quelque chose. Cependant, cela ne me dit pas ce qui a changé. Parfois, c'est ok parce que je vais juste interroger le sujet pour les dernières données, mais d'autres fois, j'ai besoin de savoir ce qui a changé exactement sur le sujet. Je remarque qu'en Java, ils ont à la fois une méthode notifyObservers () et une méthode notifyObservers (Object arg) pour probablement spécifier les détails de ce qui a changé.
Dans mon cas, j'ai besoin de savoir si l'une des deux actions différentes s'est produite sur le sujet et, s'il s'agit d'une action particulière, de connaître un nombre entier lié à cette action.
Mes questions sont donc:
- quelle est la façon C ++ de passer un argument générique (comme le fait Java)?
- Observer est-il même le meilleur modèle? Peut-être une sorte de système d'événements?
MISE À JOUR
J'ai trouvé cet article qui parle de modèle du modèle Observer: Implémentation d'un modèle Subject / Observer avec des modèles . Cela m'a fait me demander si vous pouviez mettre en forme un argument.
J'ai trouvé cette question de débordement de pile qui parle de modeler l'argument: Modèle d'observateur de sujet basé sur un modèle - Dois-je utiliser static_cast ou dynamic_cast . Cependant, le PO semble avoir un problème auquel personne n'a répondu.
L'autre chose que je pourrais faire est de changer la méthode Update pour prendre un objet EventArg comme dans:
void MyClass::Update(Subject *subject, EventArg arg)
{
...
Ensuite, créez des sous-classes de EventArg pour des données d'argument spécifiques, puis je suppose que vous les restituez à la sous-classe spécifique dans la méthode de mise à jour.
MISE À JOUR 2
A également trouvé un article, sur la création d'un framework c ++ asynchrone basé sur les messages; la partie 2 qui explique comment le sujet doit communiquer des détails sur ce qui a changé.
J'envisage maintenant sérieusement d'utiliser Boost.Signals . Utiliser mon propre modèle d'observateur était logique quand c'était simple, mais le modèle et le type d'argument commencent à se compliquer. Et j'ai peut-être besoin de la sécurité des threads de Boost.Signals2.
MISE À JOUR 3
J'ai également trouvé quelques articles intéressants sur le modèle d'observateur:
Observateur généralisant par Herb Sutter
Implémentation du modèle d'observateur en C ++ - Partie 1
Expériences de mise en œuvre du modèle de conception d'observateur (partie 2)
Expériences de mise en œuvre du modèle de conception d'observateur (partie 3)
Cependant, j'ai changé mon implémentation pour utiliser Boost.Signals qui, bien que probablement un peu gonflé à mes fins, fonctionne correctement. Et probablement aucune préoccupation de ballonnement ou de vitesse n'est pertinente.