Follow me on Instagram for more high quality images: @waynelowkashin

This post is inspired by a video series I saw on YouTube called PatternCraft, where the author, John Lindquist uses Starcraft as a subject for teaching various programming design patterns.

Recently I’ve been playing a card game called Magic the gathering, or MTG for short.  It’s a very fun game with numerous different keywords and mechanics, and almost infinite possibilities and ways to play and win.  I thought it might be fun to try and use MTG as a vehicle for explaining programming design patterns.  

Today we’re going to be looking at the decorator pattern but first of all I should probably explain a little bit about MTG for those who are less familiar with the game.

The most common way to win a game of magic is to reduce your opponents life total to 0.  This is usually, although definitely not exclusively, done by attacking your opponent with creatures.  All creature cards have the concept of power and toughness.  This is usually visible in the box in the bottom right, in the order power/toughness.

So for example, in the card below, Nyxborn Courser, we can see that the power of the creature is 2, while the toughness is 4.  If we attack our opponent with this creature, their life total will decrease by 2.

Nyxborn Courser from Theros: Beyond Death

In the format of magic I play, which is called EDH or Commander, each player’s life total starts at 40.  Hitting one opponent for 2 damage each turn is going to result in a very slow game and you will probably not live long enough to hit your opponent 20 times in order to kill them.  There are ways however to increase a creature’s power and toughness.

One way we can achieve this is by attaching pieces of equipment to it, like a sword for example.  If the sword gives a creature +1/+1 and was attached to our Nyxborn Courser, then it will deal 3 damage instead of 2, and have 5 toughness instead of 4.

In order to represent the card in code, I’m going to create a Creature class, which will have two public integer properties representing the power and toughness. These values will be passed in on creation, along with a name to identify the creature.

public class Creature : ICreature
{
    public int Power {get;}
    public int Toughness {get;}
    public string Name {get;}

    public Creature(string _name, int _power, int _toughness)
    {
        this.Power = _power;
        this.Toughness = _toughness;
        this.Name = _name;
    }
}

I’ll also create an interface for this class which defines the public properties that should be available for this card type.  Because naming is hard and I’m not very imaginative I’m just going to call this interface ICreature.

public interface ICreature
{
    int Power {get;}
    int Toughness {get;}
    string Name {get;}
}

At this point in order to represent a creature with a sword, you might be tempted to create a sub-class of Creature called CreatureAndSword, which would override the power and toughness properties and return those values + 1.  This will work but the approach isn't very scaleable.

Let’s say we wanted to introduce another equipment, say a shield, which modifies only the toughness.  We could go ahead and create a sub-class of Creature called CreatureWithShield, which might do the job, but what if we want to attach both a sword and a shield to the same creature?

For each new equipment introduced, we would need to create sub-classes for every possible combination of equipment that could be attached to that creature.  For only 2 types of equipment that's 3 additional classes, CreatureWithSword, CreatureWithShield, CreatureWithShieldAndSword

If we introduced a third type of equipment, say a helmet, then suddenly we have to implement 7 different sub-classes, 4 pieces of equipment would be 15 and suddenly you're spending your whole day writing sub-classes.

Thanks to the decorator pattern, we can avoid this unnecessary headache and introduce as many new types of equipment as we like, and equip them in any number of combinations, without the need to define countless sub-classes.  Let’s see how this works.

First of all I’m going to define a class called CreatureDecorator.  This class defines the pattern my decorator sub-classes must adhere to.  It’s going to take in a reference to a class which implements ICreature as well as, crucially, implementing the ICreature interface itself.

public class CreatureDecorator : ICreature
{
    protected ICreature _creature;

    public CreatureDecorator(ICreature creature)
    {
        this._creature = creature;
    }

    public virtual string Name => _creature.Name;
    public virtual int Power => _creature.Power;
    public virtual int Toughness => _creature.Toughness;
}

That means this class will also need to expose public properties for name, power and toughness.  What we can do, is delegate these calls to the internal instance of ICreature which we obtained through the constructor.

If we want to start decorating our creatures and equipping weapons to them, we need to create classes which define each piece of equipment.  These equipment classes will inherit from the CreatureDecorator, instead of the Creature class itself.

public class Sword : CreatureDecorator, ICreature
{
    public Sword(ICreature creature) : base(creature) {}

    public override int Toughness => base.Toughness + 1;
    public override int Power => base.Power + 1;
}

As you can see in the snippet above, I have created a Sword class which gives the creature 1 additional power and toughness.

As this equipment modifies both the power and toughness, I need to override both of those properties from the parent class, but this time instead of just returning the value of the base properties, I’m returning the value + 1.

The benefit of using the decorator pattern is that I can keep my focus solely on what the sword needs to do. I do not need to worry about any other equipment that may or may not have been attached to the creature already, when figuring out what vaules to return for power or toughness.

Nyxborn Courser with a Sword attached

As you can see from the output, a normal instance of this creature has power and toughness of 2 and 4 respectively, but when equipped with a Sword it now has 3 and 5.

I can continue to equip as many swords as I like to this creature and the power and toughness will adjust accordingly.  Maybe I want to equip a shield of some sort which will increase the Nyxborn Courser's toughness.  In that case I can create another sub-class and this time only override the toughness property.

public class Shield : CreatureDecorator, ICreature
{
    public Shield(ICreature creature) : base(creature) {}

    public override int Toughness => base.Toughness + 1;
}

By using the decorator pattern, I can attach any combination of equipment to the creature without having to write classes for each possible combination of all the different equipments.

public class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Creating a new Creature");
        ICreature creature = new Creature("Nyxborn Courser", 2, 4);

        Console.WriteLine($"Name: {creature.Name}");
        Console.WriteLine($"Base Power: {creature.Power}");
        Console.WriteLine($"Base Toughness: {creature.Toughness}");

        Console.WriteLine("Equipping a Sword to the creature..");

        creature = new Sword(creature);

        getStats(creature);

        Console.WriteLine("Equipping a Shield...");
        Console.WriteLine("Currently Equipped: Sword and Shield");

        creature = new Shield(creature);

        getStats(creature);

        Console.WriteLine("Equipping a Helmet...");
        Console.WriteLine("Currently Equipped: Sword, Shield and Helmet");

        creature = new Helmet(creature);

        getStats(creature);

        Console.WriteLine("Equipping Variable Weapon");

        creature = new Weapon(creature, 5, 10);

        getStats(creature);

        Console.ReadLine();
    }

    private static void getStats(ICreature creature)
    {
        Console.WriteLine($"New Power: {creature.Power}");
        Console.WriteLine($"New Toughness: {creature.Toughness}");
    }
}

As you can see, we can combine the equipments any way we like and get the correct results, without the need to implement dozens of new classes.

Nyxborn Courser fully equipped and ready for battle!

Another benefit of defining the equipment like this is that in future if I wanted to create another type of card which also has power and toughness values, I can still decorate the future class with the same equipment classes, so long as the new class also implements ICreature.

Of course instead of creating a class for each specific equipment, if all they do is modify the power and toughness, I could instead create a Weapon class which takes in values for power and toughness modifiers in the constructor, to save me having to create separate classes for each equipment type.

public class Weapon : CreatureDecorator, ICreature
{
    protected int _powermodifier;
    protected int _toughnessmodifier;

    public Weapon(ICreature creature, int powermod, int toughnessmod)
    : base(creature) {
        this._powermodifier = powermod;
        this._toughnessmodifier = toughnessmod;
    }

    public override int Toughness => base.Toughness + _toughnessmodifier;
    public override int Power => base.Power + _powermodifier;
}

By using the decorator pattern in this particular scenario we are gaining flexibility, encapsulating concerns, and reducing the amount of code we have to write.

I hope this post has helped explain the benefits of the decorator pattern.  If you have any feedback, or if you’re like me and enjoy playing magic, as well as coding, please feel free to leave a comment below.

Thanks for reading and keep an eye out for more posts in my “Magic the Programming” series.