The observer pattern can be really useful in event-driven systems. Here's how it might be implemented in two languages:
Java
Use an AOP library or byte-code engineering (BCEL, cglib, asm, etc) to create a sub-class on the fly. Any calls to the getter or setter of an observed property notifies any attached observers.
Objective-C
This is similar to Java - uses isa swizzling to create a sub-class on the fly. Any calls to an observed property notifies attached observers. Interestingly, in Objective-C we can swizzle back to the original class without the wrapped property methods, if all observers are removed. Whereas in Java a class is typically loaded once, so you're always notifying a (possibly empty) set of observers.
How about C++?
With limited reflection in C++, it would be difficult to use the above approaches. What is the "best" (by that I mean typical or defacto-standard) approach in C++? Is there any way to avoid the boiler-plate code like in the Java and Objective-C implementations that I referenced above? Perhaps using C++ meta-programming features?
I don't believe there is a way to implement the Observer pattern in C++ using just reflection. If you don't use any external tools, you have to implement everything manually. For instance, I'd implement it something like:
#include <iostream>
#include <set>
using namespace std;
class Impl;
class ObserverBase {
public:
virtual void propertyChanged(Impl *impl, int value) = 0;
};
class Impl {
public:
void setProperty(int value) {
if (m_property != value) {
m_property = value;
for(auto observer:m_observers) {
observer->propertyChanged(this, value);
}
}
}
int getProperty() {
return m_property;
}
void addObserver(ObserverBase *observer) {
m_observers.insert(observer);
}
private:
int m_property;
set<ObserverBase *> m_observers;
};
class Observer : public ObserverBase {
public:
virtual void propertyChanged(Impl *impl, int value) {
cout << "Saw new value of " << value << "!" << endl;
}
};
int main() {
Impl impl;
impl.addObserver(new Observer());
impl.setProperty(5);
}
If you want ObserverBase and the for loop in Impl to be auto-generated, you could parse the C++ at compile time. I don't know of anything that does that for you.
If you are using a third-party library, they may include tools to help. For instance, if you are using Qt, you could use signal/slots to notify observers of changes.