I’m fairly new at using design patterns and I am currently making a small game for my uni course that I have to use the decorator pattern for creating the different classes of NPC however I think that I have misunderstood how the decorator pattern works.
At the moment all what changes between the classes of NPC’s are the attack value, health and speed stats. What I am really unsure of is if there is a way of passing these values into the decorated object from the decorator or do i have the wrong impression of the decorator pattern.
2
Think of decorator as wrapping up an object with more functionality. Now this new object has an object inside of it, and the outer object gives it more functionality.
Here’s a little pseudo representation of it.
class Watch implements Clock
{
private Clock clockToBeDecorated;
public Watch(Clock clock)
{
clockToBeDecorated = clock;
}
public void StrappToWrist()
{
//strap the watch to your wrist
}
public DateTime GetTime()
{
return clock.GetTime();
}
}
interface Clock
{
DateTime GetTime();
}
So now we have all the functionality of a Clock but we can also strap it to our wrist (like you’d expect with a wrist). This is good when you wish to dynamically pass the object into another, so we may wish to put that click into a Watch or a PocketWatch etc.
Wikipedia has a good example using Scrolling Windows in Java as well which may help.
4
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.
- http://www.coderanch.com/t/99387/patterns/HeadFirst-Design-Patterns-Decorator-Chapter
The situation where I would envision it to be useful is:
- There is already an underlying
NPC
class, which provides basic mechanisms forgetAttack()
,getHealth()
andgetSpeed()
. - 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);
}
}
3