2011-01-19 5 views
3

s'il vous plaît excuse toute newbieness),modèle d'observateur - transmettre des informations à l'observateur

J'ai la tâche suivante à effectuer:

J'ai plusieurs classes (appeler ces A) qui se rassemblent en permanence des informations de diverses sources (base de données, internet, etc.). Ils peuvent contenir une quantité potentiellement importante d'informations sur un sujet ..

J'ai également un tas de classes (appelez ces B) qui me permettent de rendre une variété de graphiques, si fourni avec suffisamment d'informations (ici, l'information peut être aussi simple qu'une ou plusieurs valeurs flottantes).

Maintenant, je dois lier ces deux choses ensemble, de sorte que je puisse modifier quelles informations sont affichées dans quel formulaire avec des changements minimes. Maintenant, je considère utiliser un modèle d'observateur ici, car il semble se prêter bien à ce problème. Cependant, je suis un peu coincé et voudrais des conseils. Je peux clairement faire des classes A d'un type de base "source de données", qui permet aux abonnés et notifie les abonnés quand il y a des changements. Je peux aussi faire des classes B du type "observateur" et les laisser s'abonner à des sources de données et être averti des changements. Le problème est que je ne veux pas que mes observateurs connaissent un type particulier d'information qu'ils affichent. Par exemple, si je veux tracer la température dans ma ville sur l'axe des Y et le temps sur l'axe des X, et que j'ai une classe de tracé 2D (de type B), je veux éviter toute sorte d'appels A->GetTemperature(). De même, en classe A, je ne veux pas appeler NotifyOfTemperatureChange() ou quelque chose comme ça ...

Une idée est de définir un groupe de énumérations ou des chaînes comme "temperature", "time", "humidity", etc, puis dire à l'observateur que il devrait écouter (quelque chose comme A->SetYAxis (B, "temperature") - ici, j'informe la classe A qu'il devrait obtenir une seule valeur flottante pour son axe Y de la source de données B, canal "température")

de sorte que A peut simplement faire B->subscribeTo (whateverIPassedIn). De cette façon, B n'a pas besoin de savoir quelle information il trace. A peut alors dire notifyOfChangesOnThisChannel ("temperature"). Ceci, cependant, semble un peu hacky pour moi ... Par exemple, les données seraient-elles réellement passées à la fonction notifiée? Est-ce que je dois faire quelque chose comme ceci:

void B::subscriberChanged (int subscriberId, std::string channel) 
{ 
    float value = datasource [subscriberId].GetCurrentValue (channel); 
} 

ou serait quelque chose comme

void B::subscriberChanged (int subscriberId, std::string channel, void *data) 
{ 
    float value = *static_cast <float *> (data); 
} 

et d'ailleurs, comment B savoir le type de données? Je veux dire dans cet exemple c'est un flotteur, mais que faire si c'est un int ou un double? Je suppose que ma question est: est-ce correct? Existe-t-il une meilleure façon d'aborder ce problème?

Nous vous remercions à l'avance

+1

Salut! Newbieness excusé. La prochaine fois, indentez vos exemples de code de quatre espaces pour les mettre correctement en forme. –

+0

Fera. Je vous remercie. – vmpstr

Répondre

3

Vous pouvez résoudre ce problème en faisant vos observateurs des classes de modèle. Vous devrez alors définir une interface minimale (ou concept réellement) que vous pourriez appeler, par exemple, un Fact qui définirait à quoi ressemble un seul élément de données. Vous pouvez également définir un concept AxisDescription qui définit comment les axes sont décrits (étiquettes, unités, linéaires/logarithmiques, etc.).

Voici un exemple simple pour illustrer:

template<class FactType, class AxisType> 
class B { 
public: 
    b(AxisType axis); // initialization requires a description of the axis 

    // called when a new fact is available 
    void notify(FactType fact); 

    // called when many fact should be reported 
    template<class FactIterator> 
    void notify(FactIterator begin, FactIterator end); 
}; 

FactType peut être aussi simple que float ou int, mais aussi plus complexe, en fonction de ce que vous voulez faire.

+0

Hmm .. Cela ressemble à quelque chose que je n'ai pas considéré, ce qui est une bonne chose. :) Ce genre de choses simplifie. Je pense que je vais le modifier un peu en faisant de FactType une interface, de sorte que je puisse obtenir des choses comme la source du fait, le type et sa valeur. De cette façon, je peux correspondre à l'endroit où je devrais l'afficher. Je vous remercie! – vmpstr

Questions connexes