Decorators have many uses but it doesn't mean that decorator is the appropriate pattern to use for every situation. Given the same requirements, a programmer can always try implementing the same requirements in different patterns to see which one fits best.
In OP's example, I think there is one situation in which the attack, health, speed
system can be augmented with a decorator pattern.
For OP's benefit, please read the Coffee Condiment decorator pattern example in Head First Design Patterns.
The situation where I would envision it to be useful is:
- There is already an underlying
NPC
class, which provides basic mechanisms for getAttack()
, getHealth()
and getSpeed()
.
- There are a number of gadgets which could be acquired by an
NPC
object, and these gadgets would temporarily modify the acquirer's properties.
Sample code
(Disclaimer: sample code in C#, not C++)
// Just the statistics. We are not claiming that "CaffeinePack" is a character.
interface CharacterStat
{
int getAttack();
int getHealth();
int getSpeed();
}
interface Character : CharacterStat, CharacterPlanner, ...
{
// a bunch of other stuff
}
class NPC : Character
{
public int getAttack() { ... concrete implementation ... }
public int getHealth() { ... concrete implementation ... }
public int getSpeed() { ... concrete implementation ... }
}
class CaffeinePack : CharacterStat
{
private CharacterStat realObject;
public CaffeinePack(CharacterStat realObject) { this.realObject = realObject; }
public int getAttack()
{
return realObject.getAttack();
}
public int getHealth()
{
return (int)(realObject.getHealth() * 0.8);
}
public int getSpeed()
{
return (int)(realObject.getSpeed() * 1.2);
}
}