Delegates solve a fundamental problem in software design: how to allow objects to communicate without creating tight coupling between them. Let's explore why this matters with a practical example.
Consider a game where we want to update the UI when a player takes damage. The direct approach might look like this:
class Player {
public:
void TakeDamage(int Damage) {
Health -= Damage;
UserInterface->UpdateHealthBar(Health);
}
private:
UserInterface* UserInterface;
int Health{100};
};
This creates several problems:
Player
class now needs to know about UI implementation detailsPlayer
classUsing delegates solves these problems by inverting the dependency:
class Player {
public:
using DamageDelegate = std::function<
void(int NewHealth)>;
void SetOnDamageDelegate(DamageDelegate D) {
OnDamageDelegate = D;
}
void TakeDamage(int Damage) {
Health -= Damage;
if (OnDamageDelegate) {
OnDamageDelegate(Health);
}
}
private:
DamageDelegate OnDamageDelegate;
int Health{100};
};
Now:
Player
doesn't need to know anything about UIPlayer
classThis pattern is particularly valuable in game development where systems often need to be loosely coupled but still communicate effectively.
Answers to questions are automatically generated and may not have been reviewed.
An overview of the options we have for building flexible notification systems between game components