i'm trying to implement a custom version of an Observer pattern in c++.
These are my classes (just interface):
class Observer{
public:
void observe(std::string behaviour, Observable * observable);
void stopObserving(std::string behaviour, Observable * observable);
virtual void notified(std::string behaviour, Observable * observed);
// ...
};
class Observable{
public:
void notifyBehaviour(std::string behaviour);
// ...
};
And can be used like this:
class A : public Observer{
public:
void notified(std::string behaviour, Observable * observed){
if (behaviour == "jumping"){
// ...
}
}
};
class B : public Observable{
public:
void jump(){
// ...
notifyBehaviour("jumping");
}
};
int main(){
A a;
B b;
a.observe("jumping", &b);
b.jump();
// ...
}
Each class implementing Observer can register itself as observing an Observable with a behaviour.
The Observable can notify its actions with "notifyBehaviour" to everyone interested.
Each Observer listening will be notified via its method "notified".
The above works perfectly. Anyway in the example above:
void notified(std::string behaviour, Observable * observed){
if (behaviour == "jumping"){
// ...
}
i'd like to use the Observable * i'm passing to do something on the notifying object. Unfortunately i'll have to do something like this:
void notified(std::string behaviour, Observable * observed){
if (behaviour == "jumping"){
auto pointer = dynamic_cast<B *>(observed);
if (pointer)
pointer->doSomethingElse();
}
}
That's ugly and will probably create problems. For example observing two different jumping entities will need multiple castings waiting for the right one.
My question is: is it possible to pass some RTTI or call an overloaded function or a template having already the right object type? I'd like to have:
class A : public Observer{
public:
void notified(std::string behaviour, B * observed){
if (behaviour == "jumping"){
observed->doSomethingBlike();
// observed if of type B !
}
}
void notified(std::string behaviour, C * observed){
if (behaviour == "jumping"){
observed->doSomethingClike();
// observed if of type C !
}
}
};
so i just need to implement the various object types i'd like to listen.
I've tried with inheritance, templates, boost::any but still without luck.
Thanks for ideas.