Suppose we have the following class hierarchy:
class Object {
public:
virtual void update() {
// Update position
}
};
class Rocket : public Object {
public:
virtual void update() {
Object::update();
// Orientate towards target
}
};
class SparklingRocket : public Rocket {
public:
virtual void update() {
Rocket::update();
// Create sparkling particles
}
};
For obvious reason this is no good idea. For instance an inheritor of any of the classes might forget to call Base::update() and the behaviour of the program would be incomplete. As I see it, functions that implement important behaviour shouldn't be made virtual, that's something better reserved for replaceable behaviour.
So, we would probably change the architecture like that:
class Object {
public:
void update() {
// Update position
afterObjectUpdate();
}
protected:
virtual void afterObjectUpdate() {}
};
class Rocket : public Object {
protected:
virtual final void afterObjectUpdate() override {
// Orientate towards target
afterRocketUpdate()
}
virtual void afterRocketUpdate() {}
};
class SparklingRocket : public Rocket {
protected:
virtual final void afterRocketUpdate() {
// Create sparkling particles
afterSparklingRocketUpdate();
}
virtual void afterSparklingRocketUpdate() {}
};
This is pretty much what I want:
- The public interface of all classes is only the non-virtual update() - method
- When that method is called it is ensured that every update()-"submethod" is called
- Even if the one inheritor forgets to call a afterUpdate() - method, the hierarchy is stable from the base class down. This way a API could ensure its own integrity whilst in the first codeexample it would have to rely on the user to call the Base::update() method
I dislike one thing though: The name of each class is part of the after...Update() methodname. That seems like codesmell to me.
I think the general goal of keeping virtual call hierarchies stable can't be that uncommon. What is the commonly applied solution that I didn't come across yet?