Tuesday, November 29, 2011

The Abstract Factory Pattern

In our last tutorial we talked about the factory method pattern which is a useful way to separate out our object creation and delegate the creation specifics to creator subclasses.
Let's take a look at another possible Car class.
abstract class Car
{
    //A car is made up of parts like an engine and wheels.
    Engine _engine;
    Wheel[] _wheels = new Wheel[4];

    //methods...
}
Here we have a Car class complete with parts. The Engine and Wheel classes would also be abstract since their types could vary. We may want a Car with a HybridEngine or special PunctureProofWheels. Different Car subclasses like Toyota or Honda could have options for different Wheels or Engines and we want to encapsulate both the creation of Cars and its parts while keeping the whole thing flexible for extension.
This may seem daunting but there is a fairly simple pattern that can help called the Abstract Factory pattern.
In this pattern we'll make Factory interface for creating families of products like different Wheels and Engines.
So let's jump right in and make a CarPartFactory class.
interface CarPartFactory
{
    Engine CreateEngine();
    Wheel[] CreateWheels();
}
Any factory class that inherits from CarPartFactory will be responsible for which concrete parts we create. Let's make a couple to see how.
class StandardCarPartFactory : CarPartFactory
{
    public Engine CreateEngine()
    {
        return new CombustionEngine();
    }

    public Wheel[] CreateWheels()
    {
        Wheel[] wheels = new Wheel[4];
        for (int i = 0; i < wheels.Length; i++)
        {
            wheels[i] = new StandardCarWheel();
        }
        return wheels;
    }
}

class HybridCarPartFactory : CarPartFactory
{
    public Engine CreateEngine()
    {
        return new HybridEngine();
    }

    public Wheel[] CreateWheels()
    {
        Wheel[] wheels = new Wheel[4];
        for (int i = 0; i < wheels.Length; i++)
        {
            //Pucture proof wheels come standard with the hybrid.
            wheels[i] = new PunctureProofWheels();
        }
        return wheels;
    }
}
We need to make Engine and Wheel classes as well. In this example they are very simple and the ones I wrote just print out that they are being made and what type so I'll leave them out.
Each Car object with be passed a CarPartFactory in its construction that will set the chosen wheels and engine.
Let's rework our Car class a bit.
abstract class Car
{
    protected Engine _engine;
    protected Wheel[] _wheels = new Wheel[4];
       
    //This is where we'll call the factory methods to make its parts.
    public abstract void ConstructCar();

    public void Paint()
    {
        Console.WriteLine("Painting car...");
    }

    public void ApplyNewCarSmell()
    {
        Console.WriteLine("Applying new car smell...");
    }
}

class Toyota : Car
{
    //Each Car has a factory reference.
    CarPartFactory _factory;
        
    public Toyota(CarPartFactory factory)
    {
        _factory = factory;
        Console.WriteLine("New Toyota created.");
    }

    public override void ConstructCar()
    {
        //The factory creates the correct engine and wheels.
        _engine = _factory.CreateEngine();
        _wheels = _factory.CreateWheels();
    }
}

//The Honda class looks very similar.
That takes care of the Cars and the part creators. We still need our old CarLot method for creating cars and choosing the correct factory.
//This should look familiar.  It's the old Factory Method pattern!
abstract class CarLot
{
    public Car BuyCar(string type)
    {
        Car product = CreateCar(type);

        product.ConstructCar();
        product.Paint();
        product.ApplyNewCarSmell();

        return product;
    }
    //factory method...
    protected abstract Car CreateCar(string type);
}

class ToyotaCarLot : CarLot
{
    protected override Car CreateCar(string type)
    {
        CarPartFactory factory;
        //Except now the 'string type' parameter declares a factory for creating parts.
        if (type == "Hybrid")
        {
            factory = new HybridCarPartFactory();
        }
        else if (type == "Standard")
        {
            factory = new StandardCarPartFactory();
        }
        else
        {
            factory = new StandardCarPartFactory();
        }
        //And we get a Toyota...
        Car car = new Toyota(factory);
        return car;
    }
}

class HondaCarLot : CarLot
{
    protected override Car CreateCar(string type)
    {
        CarPartFactory factory;
        if (type == "Hybrid")
        {
            factory = new HybridCarPartFactory();
        }
        else if (type == "Standard")
        {
            factory = new StandardCarPartFactory();
        }
        else
        {
            factory = new StandardCarPartFactory();
        }
        Car product = new Honda(factory);
        return product;
    }
}
Both lots have a Standard and Hybrid options but the ToyotaCarLot return Toyotas and the HondaCarLot returns Hondas.
Let's test it out and buy some cars.
class Program
{
    static void Main(string[] args)
    {
        CarLot _hondaLot = new HondaCarLot();
        CarLot _toyotaLot = new ToyotaCarLot();
        Car myHybrid = _hondaLot.BuyCar("Hybrid");
        Car myStandard = _toyotaLot.BuyCar("Standard");
        Console.ReadLine();
    }
}
Running this should print out this result.

That's the Abstract Factory pattern! It encapsulates the creation of families of objects and allows for easy extension of any interface we'd like, cars or parts.

The Factory Method Pattern

There are a couple rules of thumb for design and refactoring that are pretty useful. The first, as one might put it, is to stay abstract. That is, program to interfaces or abstract classes and have your objects deal with them, rather than concrete classes. This is because we want extendability in our designs. If we stick to dealing with interfaces, we can pass along any class that inherits from that interface without issue.
Another important paradigm is to separate what changes from what stays the same and encapsulate what changes.
We've seen both of these at work in every pattern so far. In the strategy pattern we encapsulated object behavior to allow it to change flexibly during runtime.
Now we're going to look at object creation and apply the same principles.
Taking the car example again, let's say before a car can be shipped out it needs to be prepared.
public abstract class Car
{
    //Each type of car handles these differently.
    public abstract void ConstructCar();
    public abstract void Paint();   
    public abstract void ApplyGloss();

    public void ApplyNewCarSmell()
    {
        //They really do this!
        Console.WriteLine("Spraying new car smell into car...");
    }
}
Every car that comes off the lot has to have these methods called on it before it's ready.
So often times when we get to creating the cars we get code that looks like this:
public Car BuyCar(string type)
{
    Car myCar;

    if (type == "Honda")
    {
        myCar = new Honda();
    }
    else if (type == "ElCamino")
    {
        myCar = new ElCamino();
    }
    else if (type == "Toyota")
    {
        myCar = new Toyota();
    }
    //etc...

    //prepare the car for purchase.
    myCar.ConstructCar();
    myCar.Paint();
    myCar.ApplyGloss();
    myCar.ApplyNewCarSmell();

    return myCar;
}
This clearly gets out of hand but what we can see is that the type of car varies but the initialization of the car is the same.
Each type of car knows how to paint itself and apply gloss, and spraying new car smell is the same for every car.
So we should try to separate out the creation and encapsulate it.
Let's do this by creating a class that handles Car creation.
public class SimpleCarFactory
{
    public Car CreateCar(string type)
    {
        Car myCar;

        if (type == "Honda")
        {
            myCar = new Honda();
        }
        else if (type == "ElCamino")
        {
            myCar = new ElCamino();
        }
        else if (type == "Toyota")
        {
            myCar = new Toyota();
        }
        //etc...
        
        return myCar;
    }
}
Now let's create a client class to buy cars from.
public class CarLot
{
    //Contains a reference to a factory object.
    SimpleCarFactory _carFactory;
    
    public CarLot(SimpleCarFactory carFactory)
    {
        _carFactory = carFactory;
    }

    public Car BuyCar(string type)
    {
        //Delegates creation to the factory object.
        Car product = _carFactory.CreateCar(type);

        //This is the same...
        product.ConstructCar();
        product.Paint();
        product.ApplyGloss();
        product.ApplyNewCarSmell();
        
        return product;
    }
}
This is called a Simple Factory. It's commonly used but isn't technically considered a design pattern.
What we would ideally like is a higher level of abstraction in the Creator class. There may be different CarLots that prepare there cars differently. Maybe certain brands of paint aren't available in certain regions or worse the steering wheel is on a different side!

This conveniently brings us to the Factory Method Pattern. Let's change our CarLot class a little:
public abstract class CarLot
{
    public Car BuyCar(string type)
    {
        //Now this calls a method from within our CarLot.
        Console.WriteLine("Creating your " + GetType().ToString());
        Car product = CreateCar(type);

        product.ConstructCar();
        product.Paint();
        product.ApplyGloss();
        product.ApplyNewCarSmell();
        
        return product;
    }

    //Each CarLot handles their own Car creation.
    protected abstract Car CreateCar(string type);
}
And make two different lots, a Unitited States CarLot and a United Kingdoms CarLot.
public class USCarLot : CarLot
{
    protected override Car CreateCar(string type)
    {
        Car product;
        if (type == "Honda")
        {
            //We have new subclasses for US Cars now.
            product = new USHonda();
        }
        else if (type == "Toyota")
        {
            product = new USToyota();
        }
        //etc...
        else
        {
            return null
        }
        return product;
    }
}

public class UKCarLot : CarLot
{
    protected override Car CreateCar(string type)
    {
        Car product;
        if (type == "Honda")
        {
            //And new subclasses for UK Cars now.
            product = new UKHonda();
        }
        else if (type == "Toyota")
        {
            product = new UKToyota();
        }
        //etc...
        else
        {
            return null
        }

        return product;
    }
}
Now for the cars.
public class USHonda : Car
{
    public override ConstructCar()
    {
        Console.WriteLine("Steering wheel goes on the left.");
    }

    public override Paint()
    {
        Console.WriteLine("Painting car...");
    }

    public override ApplyGloss()
    {
        Console.WriteLine("Applying glossy finish...");
    }

}

public class UKHonda : Car
{
    public override ConstructCar()
    {
        Console.WriteLine("Steering wheel goes on the right.");
    }

    public override Paint()
    {
        Console.WriteLine("Painting car...");
    }

    public override ApplyGloss()
    {
        Console.WriteLine("Applying glossy finish...");
    }
}

//In our simple example, the Toyota classes look similar...
Now let's say we want to buy a car. First we choose a type of CarLot to make, then we choose the type of car we want, finally we call the the CarLot's BuyCar method passing in the appropriate string. The type of care that comes out depends on the CarLot that we chose.
class Program
{
    static void Main(string[] args)
    {
        CarLot usCarLot = new USCarLot();
        CarLot ukCarLot = new UKCarLot();

        Car myUSHonda = usCarLot.BuyCar("Honda");
        Car myUKHonda = ukCarLot.BuyCar("Honda");

        Console.ReadLine();
    }
}
And the output should read:

Creating your USHonda
Steering wheel goes on the left.
Painting car...
Applying glossy finish...
Creating your UKHonda
Steering wheel goes on the right.
Painting car...
Applying glossy finish...


That's the Factory Method pattern and it, like all factories, encapsulates object creation. It gives us an interface for creating objects while allowing specific instances of that interface to decide which class to instantiate.
To wrap up, let's take a look at the class diagram.

In the Creator we have a 'factory method' that all subclasses must implement so the ConcreteCreator actually makes the product and is responsible for which ConcreteProduct to make.
Each ConcreteProduct must implement the Product interface so that classes dealing with the products all have a common interface they know how to manipulate.

That's it for this article and thanks for reading!

Sunday, November 27, 2011

The XML Content Importer

A while ago, I wrote a quick rundown of XNA's Content Pipeline, the classes needed to extend it and how they work together. However for the most part, one wouldn't need to do all that since the built in XML Importer is so powerful. One can load almost any class through the content pipeline using only XML.
We'll go few some examples to illustrate this.
If you want to follow along with the code, go ahead and make a new XNA Game Project. I named mine XMLPipelineTutorial.
Right click on the Content Project, select Add New Item... and select XML file. I named mine SimpleString.xml because that's what it will load. The following XML should appear:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <!-- TODO: replace this Asset with your own XML asset data. -->
  <Asset Type="System.String"></Asset>
</XnaContent>
The Node named Asset has an attribute called Type which is set to "System.String". This is what will be returned when we call the Content Manager's Load method.
What we put inside the Asset tags is the actual content
I've changed the XML to look like this:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="System.String">
    Hello World!
  </Asset>
</XnaContent>
Now in Game1.cs I changed the LoadContent() method so it looks like this:
protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    string xmlContent = Content.Load<string>("SimpleString");
    Console.WriteLine(xmlContent);
}
The line Console.WriteLine(xmlContent) is a little trick I use for debugging games when I don't want to bother loading a font and drawing it on the screen. The output appears on the 'Output' window which you can find in Visual Studio via Debug -> Windows -> Output.
Easy enough. We can load arrays of things:

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <!-- TODO: replace this Asset with your own XML asset data. -->
  <Asset Type="System.Int32[]">
    4 5 1 6 9 4 10 100032
  </Asset>
</XnaContent>
I named this one IntegerArray.xml.
We can load this just as easily.

protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    string xmlContent = Content.Load<string>("SimpleString");
    Console.WriteLine(xmlContent);

    int[] xmlContent2 = Content.Load<int[]>("IntegerArray");
    for (int i = 0; i < xmlContent2.Length; i++)
    {
        Console.WriteLine(xmlContent2[i].ToString());
    }
}
This is all very well and good but doesn't really show off the flexibility. Let's import a Dictionary of Vectors keyed by Rectangles just for kicks.

<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <!-- TODO: replace this Asset with your own XML asset data. -->
  <Asset Type="System.Collections.Generic.Dictionary[Microsoft.Xna.Framework.Rectangle, 
         Microsoft.Xna.Framework.Vector2]">
    <Item>
      <Key>0 12 24 5</Key>
      <Value>5 5.4</Value>
    </Item>
    <Item>
      <Key>12 3 6 2</Key>
      <Value>0 0</Value>
    </Item>
  </Asset>
</XnaContent>
Each KeyValuePair in the Dictionary is put in between Item nodes. We could had done this for the simple array but we don't have to. Each Key and Value is inside a node of the same name. The XML importer uses reflection to figure out what's what (which is why it's so flexible and powerful).
The Keys, being rectangles are just a list of int's representing X, Y, Width and Height respectively and the Values being Vectors are written as two float's X and Y, respectively. For some reason the pipeline expects these to be in this format and won't let me put values between Width/Height tags or X/Y tags. I suppose for convenience.
Now to load and test it out.
protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    Dictionary<Rectangle, Vector2> xmlContent = 
        Content.Load<Dictionary<Rectangle, Vector2>>("VectorRectangleDictionary");

    foreach (Rectangle rectangle in xmlContent.Keys)
    {
        Console.WriteLine(rectangle.ToString());
    }

    foreach (Vector2 vector in xmlContent.Values)
    {
        Console.WriteLine(vector.ToString());
    }
}
And all is as it should be.
But these are all classes from preexisting libraries, one might point out, what if I want to load my own class?
Not a problem! Since the XML importers uses reflection, we can load any class we want through it.
To do this though we must add a Game Library Project to keep any classes we want to load. Then add a reference to that project in the content project.
We need the Library Project because the content project doesn't know anything about the XMLPipelineTutorial namespace so it won't be able to find any types you try to give it and trying to add a reference to it would cause a circular dependency.
Remember to add a reference to the Game Library not only in the content project but also the main game project.
Here's a simple class:
public class GameItem
{
    public string Name = null;
    public double Value;
}
And here's an XML file for loading it:
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="XMLTutorialData.GameItem">
    <Name>Sword</Name>
    <Value>350</Value>
  </Asset>
</XnaContent>
Make sure the namespace in the Type attribute match yours.
Now we can load it just like any other asset
protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    GameItem item = Content.Load<GameItem>("Item");

    Console.WriteLine(item.Name + " " + item.Value.ToString());
}
And you should see, "Sword 350" in the output window.
There is a subtlety here that's worth pointing out. To illustrate I've defined another GameItem object and loaded it with the same file. Here's the new LoadContent method. See if you can predict the output before running.
protected override void LoadContent()
{
    // Create a new SpriteBatch, which can be used to draw textures.
    spriteBatch = new SpriteBatch(GraphicsDevice);

    GameItem itemOne = Content.Load<GameItem>("Item");
    GameItem itemTwo = Content.Load<GameItem>("Item");

    Console.WriteLine(itemOne.Name + " " + itemOne.Value.ToString());
    Console.WriteLine(itemOne.Name + " " + itemOne.Value.ToString());

    //Changed the name of itemOne...
    itemOne.Name = "Boot";

    //Print out the name of itemTwo.
    Console.WriteLine(itemTwo.Name);
}
What the?! Changing itemOne's name changed itemTwo's name as well! This is because GameItem is a reference object. What we have are two references to the same object. Go ahead and try this with a value type like a single integer or a Vector2 object and you won't get the same behavior.

The importer will by default only deserialize public fields and properties. If you have private fields you'd like to add you must mark them with a [ContentSerializer] attribute and if you have public fields or properties you'd like ignored by the serializer, you must use the [ContentSerializerIgnor] attribute (excluding readonly fields and properties).
So let's change the GameItem class so not everything is public.
public class GameItem
{
    [ContentSerializer]
    string _name = null;
    [ContentSerializer]
    double _value;

    public string Name
    {
        get { return _name; }
    }

    public double Value
    {
        get { return _value; }
    }
}
The Name and Value properties are readonly so they don't require an attribute to ignore them.
Here's the new Item.xml where the node names match the new field names
<?xml version="1.0" encoding="utf-8" ?>
<XnaContent>
  <Asset Type="XMLTutorialData.GameItem">
    <_name>Sword</_name>
    <_value>350</_value>
  </Asset>
</XnaContent>
And this works exactly the same as before except the GameItem class is better encapsulated.
That's all for now. The built in XML importer has a lot of features and is quite flexible. There's a lot more to explore and perhaps I'll go into more in future articles.

Update: I cam across this question in StackOverflow where someone's demonstrated a nice way to print out how exactly the intermediate serializer expects to see your .xml formatted for some specific object. Definitely worth checking out.

Saturday, November 26, 2011

The State Pattern

The State Pattern allows for a class to change its behavior dynamically according to an internal state.
Let's say we want to design an Enemy class for a game. An Enemy object will be behaving differently depending on it's hit points or other stats, or what's happening around it in the world. If its hit points are low then maybe we use a different animation where it limps and if its hit points reach zero it dies. If it's aware of the Player it may start chasing, attacking, or evading behavior or when nothing in particular is going on perhaps it wanders around or patrols an area.

First let's try representing the Enemy's state with an enumerator giving it only a couple states at first and throw together a quick Enemy class with some methods.
public enum EnemyState
{
    Idle,
    Dead,
}

public class Enemy
{
    int _hitPoints = 20;
    EnemyState _state = EnemyState.Idle;
    
    public void WanderAround()
    {
        if (_state != EnemyState.Dead)
        {
            _state = EnemyState.Idle;
            Console.WriteLine("The Enemy aimlessly wanders...");
        }
        else
        {
            Console.WriteLine("The Enemy is dead so it can't wander around.");
        }
    }

    public void TakeDamage(int damage)
    {
        if (_state != EnemyState.Dead)
        {
            _hitPoints -= damage;
            Console.WriteLine("Enemy takes " + damage.ToString() + " points of damage");
            if (_hitPoints <= 0)
            {
                _state = EnemyState.Dead;
                Console.WriteLine("Enemy is dead!");
            }
        }
        else
        {
            Console.WriteLine("Hit points already at zero.");
        }
    }
    
    public void Attack()
    {
        if (_state != EnemyState.Dead)
        {
            Console.WriteLine("The Enemy attacks!");
        }
    }
}
Pretty straight forward. The methods' behaviors depend on the internal state object, and the state is changed depending on internal conditions, completely hidden from the user. Seems okay until we need to add new states. Let's add an Evading state.
public enum EnemyState
{
    Idle,
    Dead,
    Evading,
}

public class Enemy
{
    int _hitPoints = 20;
    EnemyState _state = EnemyState.Idle;
    
    public void WanderAround()
    {
        if (_state == EnemyState.Dead)
        {
            Console.WriteLine("The Enemy is dead so it can't wander around.");
        }       
        else if (_state == EnemyState.Evading)
        {
            Console.WriteLine("The Enemy can't wander around while it's running away!");
        }
        else 
        {
            _state = EnemyState.Idle;
            Console.WriteLine("The Enemy aimlessly wanders...");
        }
    }

    public void TakeDamage(int damage)
    {
        if (_state != EnemyState.Dead)
        {
            _hitPoints -= damage;
            Console.WriteLine("Enemy takes " + damage.ToString() + " points of damage");
            
            if (_hitPoints <= 5)
            {
                //If the enemy's hit points drops low enough it 
                //becomes scared and runs away.
                _state = EnemyState.Evading;
                Console.WriteLine("Enemy is running away!");
            }
            if (_hitPoints <= 0)
            {
                _state = EnemyState.Dead;
                Console.WriteLine("Enemy is dead!");
            }
        }
        else
        {
            Console.WriteLine("Hit points already at zero.");
        }
    }
    
    //A method to call when the enemy 'feels safe'
    //enough to go back to its Idle state.
    public void StopEvading()
    {
        if (_state == EnemyState.Dead)
        {
            Console.WriteLine("The enemy is dead");
        }
        else
        {
            _state = EnemyState.Idle;
            //Start wandering aimlessly...
            WanderAround();
        }
    }

    public void Attack()
    {
        if (_state == EnemyState.Dead)
        {
            Console.WriteLine("The Enemy can't attack while dead.");
        }
        else if (_state == EnemyState.Evading)
        {
            Console.WriteLine("The Enemy won't attack if it's running away.");
        }
        else
        {
            Console.WriteLine("The Enemy attacks!");
        }
    }
}
Keeping track of the internal state is starting to become complicated. Every time we add a new state we need to account for it in every method, and if we want to add a method we need to account for the state how the state effects it and how it may change the state.
The State Pattern handles this by representing a state as an object itself. These state objects will handle the enemy's behavior when it is in the corresponding state.
Each State class will implement methods to handle requests from the enemy.
Let's look at some code. First we'll implement a State interface. This will replace our enum entirely.
public interface EnemyState
{
    void HandleWanderAround();
    void HandleDamage(int hitPoints);
    void HandleStopEvading();
    void HandleAttack();
}
Notice the method stubs are similar but not exactly like the ones in the Enemy class. The enemy will make requests to its state which will call the appropriate handling method.
Now let's rework the Enemy class.
public class Enemy
{
    int _hitPoints = 20;
    EnemyState _state;
    
    public Enemy()
    {
        //We need to initialize the state to something other than null.
        _state = new IdleState(this);
    }

    public void WanderAround()
    {
        _state.HandleWanderAround();
    }

    public void TakeDamage(int damage)
    {
        _hitPoints -= damage;
        _state.HandleDamage(_hitPoints);
    }
   
    public void StopEvading()
    {
        _state.HandleStopEvading();
    }

    public void Attack()
    {
        _state.HandleAttack();
    }

    public EnemyState GetState()
    {
        return _state;
    }

    public void SetState(EnemyState state)
    {
        _state = state;
    }
}
Much more concise, let's code our IdleState class to see how this works.
public class IdleState : EnemyState
{
    Enemy _enemy;

    public IdleState(Enemy enemy)
    {
        _enemy = enemy;
    }

    public void HandleWanderAround()
    {
        Console.WriteLine("The enemy wanders around.");
    }

    public void HandleDamage(int hitPoints)
    {
        if (hitPoints <= 5 && hitPoints > 0)
        {
            _enemy.SetState(new EvadingState(_enemy));
        }
        if (hitPoints <= 0)
        {
            _enemy.SetState(new DeadState(_enemy));
        }
    }

    public void HandleStopEvading()
    {
        Console.WriteLine("The enemy isn't evading.");     
    }

    public void HandleAttack()
    {
        Console.WriteLine("The enemy attacks!");
    }
}
No long string of state checks required since we know that if these methods are being called, then this is the state the enemy is in. We have a reference to the enemy in case we want to set it's state from another.
Let's finish up with our DeadState and EvadingState classes.
public class EvadingState : EnemyState
{
    Enemy _enemy;

    public EvadingState(Enemy enemy)
    {
        _enemy = enemy;
    }

    public void HandleWanderAround()
    {
        Console.WriteLine("The enemy can't wander around if it's evading!");
    }

    public void HandleDamage(int hitPoints)
    {
        if (hitPoints <= 0)
        {
            _enemy.SetState(new DeadState(_enemy));
        }
    }

    public void HandleStopEvading()
    {
        _enemy.SetState(new IdleState(_enemy));
        _enemy.WanderAround();   
    }

    public void HandleAttack()
    {
        Console.WriteLine("The enemy won't attack if it's running away.");
    }
}
public class DeadState : EnemyState
{
    Enemy _enemy;

    public DeadState(Enemy enemy)
    {
        _enemy = enemy;
    }

    public void HandleWanderAround()
    {
        Console.WriteLine("The enemy can't wander around if it's dead!");
    }

    public void HandleDamage(int hitPoints)
    {
        Console.WriteLine("The enemy is already dead.");
    }

    public void HandleStopEvading()
    {
        Console.WriteLine("The enemy is dead.");   
    }

    public void HandleAttack()
    {
        Console.WriteLine("The enemy can't attack if it's dead.");
    }
}
Everything about an enemy's behavior while it's in a certain state is encapsulated in these State classes. We can change State behavior easier because we know where all the code associated with that state is and we can easily add new States without altering much existing code.
If you've noticed a similarity between the State Pattern and the Strategy Pattern, that's no coincidence; they're very similar. However the State Pattern acts more autonomously, switching from one state to the other based on internal criteria, on its own without the user even being aware of it. The user just calls the Enemy's methods and get the correct behavior!
Thanks for reading and I hope you're enjoying this series on design patterns!

Friday, November 25, 2011

The Singleton Pattern

The Singleton Pattern is a way of making sure that only one instance of a class gets instantiated. It also sets up a global access point for the object.
Having a class that we can only have one instance of can be useful if, say, our class held a sort of global library of data. The Singleton would make sure there'd never be any confusion over the values of our data, ie. they never come up with two conflicting values, and we would also have a way of retrieving things from our global pool of data from anywhere.
The UML diagram looks very trivial for this pattern because of how simple it is. However, it does have its subtleties. Let's take a look.


The class contains an instance of itself (the one and only one instance) and a method for retrieving that instance.
Let's take a closer look

public class Singleton
{
    static Singleton _uniqueInstance;
    
    Singleton() { }

    public static Singleton GetInstance()
    {
        if (_uniqueInstance == null)
        {
            _uniqueInstance = new Singleton();
        }
        return _uniqueInstance;
    }
}
Perhaps you've noticed the private constructor. This is the key to the pattern. With a private constructor, we can only call new Singleton() from within the Singleton class itself. This allows us to have the class carefully monitor how it's instantiated through the public static method Singleton.GetInstance(), our global access point to the unique instance.
The first time we call Singleton.GetInstance(), the method checks to see if _uniqueInstance is null and since it is, it assigns a new Singleton() to _uniqueInstance and returns it.
The next time we call Singleton.GetInstance() (and every time afterwards), the check for null, returns false and the method returns the one and only one instance.

There is a problem with this set up as is though and maybe you've already noticed it. It isn't thread safe. If two threads were both accessing Singleton.GetInstance(), we could run into problems. Let's walk through a possible method call to see why.

Thread 1:
if (_uniqueInstance == null) //Thread 1 evaluates this to true

Thread 2 gets a turn:
if (_uniqueInstance == null) //Thread 2 also evaluates this to true

Thread 1:
_uniqueInstance = new Singleton(); //Thread 1 creates a new object.
return _uniqueInstance;

Thread 2's turn once again
_uniqueInstance = new Singleton(); //Thread 2 calls the constructor again.
return _uniqueInstance;
Oh no! Since Thread 2 had already evaluated true for the null check, it calls the constructor again and we get a second instance of _uniqueObject completely breaking everything!
Luckily, there's a way around this using the lock keyword.
lock essentially forces a thread to complete a section of code before another thread can get a turn.
Here's our new Singleton class:
public class Singleton
{
    static Singleton _uniqueInstance;
    static readonly object padLock = new object();

    Singleton() { }

    public static Singleton GetInstance()
    {
        lock(padLock)
        {
            if (_uniqueInstance == null)
            {
                _uniqueInstance = new Singleton();
            }
            return _uniqueInstance;
        }
    }
}

That's it! A simple but powerful way to make sure an object only ever has one instance.

Thanks for reading!

The Decorator Pattern

Subclassing is a powerful way of extending the behavior of a class while keeping what was already there intact. And is, of course, an integral part of object oriented programming. It does however have its drawbacks. I'll illustrate some with a simple example.

Let's say you're in a shop selling a dagger. Maybe there is a base price for the dagger but what you get for the dagger can rely on many factors. The type and quality of the dagger for example, and perhaps there's even an enchantment on it that increases it's value.
So, let's say a dagger class looks something like this:
public abstract class Dagger
{
    public abstract double GetValue();
}
Short, yes but this is all we need for our example.
We'll make a new class now, BronzeDagger, that will inherit from our Dagger class.
public class BronzeDagger : Dagger
{   
    public double GetValue()
    {
        //Return the dagger's base value.
        return 200d;
    }
}
Seems okay so far... we could continue, easily enough to make more classes for Iron, Silver, etc.
But what about that enchantment? If we were to continue in this fashion we'd be forced to make EnchantedBronzeDagger classes and EnchantedSilverDaggerClasses.

Perhaps though, one might suggest that we simply keep track of fields inside the base class like condition and an enchantment type of some kind. Let's see what that would look like.
public abstract class Dagger
{
    double _conditionFactor = .74d;
    double _enchantmentFactor = 2d;

    public abstract double GetValue();

    public double GetConditionFactor()
    {
        return _conditionFactor;
    }

    public double GetEnchantmentFactor()
    {
        return _enchantmentFactor;
    }
}

public class BronzeDagger : Dagger
{
    public double GetValue()
    {
        return 200d * GetCondition() * GetEnchantmentFactor();
    }
}

public class SilverDagger : Dagger
{
    public double GetValue()
    {
        return 500d * GetCondition() * GetEnchantmentValue();
    }
}

However, as more price altering factors are needed, the amount of code we have to write gets out of hand and we'd be forced to change the base class code each time.

The Decorator Pattern allows us to extend behavior dynamically without subclassing and without altering existing code.
The basic idea is to encapsulate the extended behavior into their own classes. We 'wrap' these extended behaviors, or decorators around the class we wish to add to.

Here's what a UML diagram for the Decorator pattern looks like:

The Component would be the object we wish to decorate. The Decorator class inherits from this base class and also contains a reference to one. In this diagram it's the abstract decorator that contains a Component reference which is fine, probably ideal, but for this quick example the Component reference is kept in the ConcreteDecorator classes. Finally there is a ConcreteComponent which inherits from the Component class as well.
That's the set-up, but how we use it will become clearer as we move along.

In our example we'd still have our base abstract Dagger (our Component) class:
public abstract class Dagger
{
    public abstract double GetValue();
}
And some subclasses:
public class BronzeDagger : Dagger
{
    public double GetValue()
    {
        return 200d;
    }
}

public class SilverDagger : Dagger
{
    public double GetValue()
    {
        return 200d;
    }
}

Now we'll make our abstract decorator class.
public abstract class DaggerDecorator : Dagger
{
    public abstract double GetValue();
}
It's important to note here while decorator class inherits from Dagger we're not using it in the normal sense. We're using it here for the type matching or mirroring. Let's make some concrete decorators.
public abstract class EnchantmentDecorator : DaggerDecorator
{
    //We have a reference to the object (or its outer most wrapper)
    //that we're decorating.
    Dagger _dagger;

    //The constructor gets passed a dagger which can 
    //be a decorator since the types match.
    public EnchantmentDecorator(Dagger dagger)
    {
        _dagger = dagger;
    }

    public double GetValue()
    {
        //This decorator multiplies the value by two.
        return 2 * _dagger.GetValue();
    }
}

public abstract class ConditionDecorator : DaggerDecorator
{
    //We have a reference to the object (or its outer most wrapper)
    //that we're decorating.
    Dagger _dagger;
    
    //The constructor gets passed a dagger which can 
    //be a decorator since the types match.
    public Decorator(Dagger dagger)
    {
        _dagger = dagger;
    }

    public double GetValue()
    {
        return .75d * _dagger.GetValue();
    }
}
Each decorator adds its own contribution to the value by delegating the method call, GetValue().
Let's see this in action and create a dagger, decorate it and find its value.

class Program
{
    static void Main(string[] args)
    {
        //Create a BronzeDagger...
        BronzeDagger _kitchenKnife = new BronzeDagger();

        //Wrap it in an EnchantMentDecorator...
        _kitchenKnife = new EnchantmentDecorator(_kitchenKnife);
        
        //Make a SilverDagger.
        SilverDagger _sting = new SilverDagger();
        //This one gets two decorators.
        _sting = new ConditionDecorator(_sting);
        _sting = new EnchantmentDecorator(_sting);
        
        double stingValue = _sting.GetValue();
        double knifeValue = _kitchenKnife.GetValue();

        Console.WriteLine(stingValue.ToString());
        Console.WriteLine(knifeValue.ToString());
    }
}
When we call _sting.GetValue(), it first calls the EnchantmentDecorator's GetValue() method, which then calls the ConditionDecorator's GetValue() which finally calls the original SilverDagger's GetValue() and each call contributes to the final value in some way.
In this example, only multiplication was used in calculating the final value, so the order in which I wrapped them and the order that each decorator delegated its behavior didn't matter. In more complicated examples these things have to be taken into account. We can add as many decorators to an object that we want, extending the class's functionality any time, and the original Dagger class and its subclasses are never altered in the process. Decorators can even add new methods.

Well, that's the Decorator Pattern in a nutshell! I hope you are enjoying this series and thanks for reading!

Wednesday, November 23, 2011

The Observer Pattern

Often times, objects need to know what other objects are up to. They may need to be updated of changes and passed new data.
A common example is the view or UI of a program needs to be aware of the state of the objects. In a game, the HUD (Heads Up Display) may need to know information like the players hit points, ammo, or score.
This can be easily achieved through the Observer Pattern. The classes that are kept up to date are called observers and the object being observed is often called the subject. The subject usually has a collection of observers as well as methods for adding or removing observers, also called registering and unregistering respectively. There must also be a way of notifying the registered observers of new data when necessary.
Like many design patterns there are multiple ways doing things and the observer pattern is no exception. I'll go into two main ways that observers are notified of change.

Here's a quick look at a UML diagram for the Observer pattern.


In our simplified example we'll stick with the gaming theme where our subject will be a player, and our observer will be the HUD that will be notified of any change to the player's hit points so that it can be displayed. There can be any number of observers, but we'll stick with one for now. (In fact Observers can register with multiple Subjects, Subjects can, themselves be Observers and vice-versa but we'll keep things simple for now.)

First we'll need our observer interface. It will simply contain a method stub for receiving new data.
public interface IObserver
{
    void Update(double hitPoints);
}

Our Subject contains stubs for adding and removing observers and notifying them of changes.
public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void UnregisterObserver(IObserver observer);
    void NotifyObservers();
}

Let's code our Player class. This will inherit from ISubject and will need to contain a collection of observers and data to be observed.
public class Player : ISubject
{
    //Here's some data that needs to be observed.
    double _hitPoints = 20;

    //We need a collection of observers to notify.
    List<IObserver> _observers = new List<IObserver>();

    //Here's the method that actually changes the hitpoints.
    public void TakeDamage(double damageTaken)
    {
        _hitPoints -= damageTaken;
        //Once this field has been altered, 
        //we automatically notify its observers.
        StateChanged();
    }
   
    public void StateChanged()
    {
        //The observers are notified whenever the class's state, 
        //in this case the Player's hit points changes.
        NotifyObservers();
    }

    public void RegisterObserver(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void UnregisterObserver(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void NotifyObservers()
    {
        //Here we simply iterate through each registered 
        //observer and pass each one
        //the current hitpoints.
        foreach (IObserver observer in _observers)
        {
            observer.Update(_hitPoints);
        }
    }
}
Notice that whenever the _hitPoints field is changed we call StateChanged() which notifies each observer of the new _hitPoints value.

Now for our concrete observer, the HUD, which will display the Player's hit points if it's registered with it.
class HUD : IObserver
{
    double _hitPointsToDisplay;
    
    //Here is where the observer receives its new data.
    public void Update(double hitPoints)
    {
        _hitPointsToDisplay = hitPoints;
    }

    public void DisplayHitPoints()
    {
        Console.WriteLine("Hit Points: ");
        Console.WriteLine(_hitPointsToDisplay.ToString());
    }   
}
We can now set up a simple test:
class Program
{
    static void Main(string[] args)
    {
        Player _player = new Player();
        HUD _hud = new HUD();

        //Register the HUD observer.
        _player.RegisterObserver(_hud);

        //Once all the observers are registered we'll 
        //initialize them with the proper data.
        _player.StateChanged();

        _hud.DisplayHitPoints();

        //The player takes some damage.  Remember that this 
        //method automatically notifies all
        //observers so there's no reason to call 
        //the NotifyObservers() method again.
        _player.TakeDamage(15.25);

        //The HUD displays the new data.
        _hud.DisplayHitPoints();

        Console.ReadLine();
    }
}

And it works as promised. Every time the Player takes damage (the TakeDamage() method is called), the HUD is notified of the change and we can display it on the screen.

However, there will almost definitely be other data associated with the concrete subject that the observers will need to be aware of.
The Player may have a Score for example. So we'll need to change the classes a bit.
public interface IObserver
{
    void Update(double hitPoints, int score);
}

The Player class now has a score field and a method for incrementing it. Here's the entire Player class with the new changes.
public class Player : ISubject
{
    //Here's some data that needs to be observed.
    double _hitPoints = 20;
    int _score = 0;

    //We need a collection of observers to notify.
    List<IObserver> _observers = new List<IObserver>();

    //Here's the method that actually changes the hitpoints.
    public void TakeDamage(double damageTaken)
   {
        _hitPoints -= damageTaken;
        //Once this field has been altered, we automatically notify its observers.
        StateChanged();
   }

    //This method adds to the player's score.
    public void AddScore(int score)
    {
        _score += score;
        //And again, we notify observers.
        StateChanged();
    }

    public void RegisterObserver(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void UnregisterObserver(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void StateChanged()    
    {        
        //The observers are notified whenever the class's state,
        //in this case the Player's hit points changes.
        NotifyObservers();
    }

    public void NotifyObservers()
    {
        //Here we simply iterate through each registered 
        //observer and pass each one the current hitpoints.
        foreach (IObserver observer in _observers)
        {
            observer.Update(_hitPoints, _score);
        }
    }
}

Finally the HUD needs to be modified to reflect these changes.
class HUD : IObserver
{
    double _hitPointsToDisplay;
    //Here's the new data that the HUD is interested in keeping up to date with.
    int _scoreToDisplay;

    //Here is where the observer receives its new data.
    public void Update(double hitPoints, int score)
    {
        _hitPointsToDisplay = hitPoints;
        _scoreToDisplay = score;
    }

    public void DisplayHitPoints()
    {
        Console.WriteLine(_hitPointsToDisplay.ToString());
    }

    public void DisplayScore()
    {
        Console.WriteLine(_scoreToDisplay.ToString());
    }
}

Here's the modified program class.
class Program
{
    static void Main(string[] args)
    {
        Player _player = new Player();
        HUD _hud = new HUD();

        //Register the HUD observer.
        _player.RegisterObserver(_hud);

        //Once all the observers are registered we'll 
        //initialize them with the proper data.
        //We can also do this in the concrete observers' constructors.
        _player.NotifyObservers();

        //Display initial values.
        _hud.DisplayHitPoints();
        _hud.DisplayScore();

        //The player takes some damage.  Remember that this 
        //method automatically notifies all
        //observers so there's no reason to call 
        //the NotifyObservers() method again.
        _player.TakeDamage(15.25);

        //The player receives a score for some reason...
        _player.AddScore(5);

        //The HUD displays the new data.
        _hud.DisplayHitPoints();
        _hud.DisplayScore();

        Console.ReadLine();
    }
}

We can already see some problems cropping up. Each piece data we start adding in the player class, we'll need to modify the all the classes that inherit from IObserver.
One way to deal with this is to modify the IObserver interface so that it's Update method stub takes an object as a parameter so one could pass any type of data. It would then be up to the concrete observer class to interpret the argument, which can be tricky. I've set this example up so that each piece of data is of a different type so we won't run into a lot of problems.

Here's our modified IObserver interface.
public interface IObserver
{
    void Update(object arg);
}

The ISubject interface also needs to change.
public interface ISubject
{
    void RegisterObserver(IObserver observer);
    void UnregisterObserver(IObserver observer);
    void NotifyObservers(object arg);
}

The new HUD will receive data as an object type, interpret it and update the appropriate fields.
class HUD : IObserver
{
    double _hitPointsToDisplay;
    int _scoreToDisplay;

    //Here is where the observer receives its new data.
    public void Update(object arg)
    {
        //It's up to the observer to handle the argument passed
        //to it, which can be quite a hassle!
        if (arg is double)
        {
            _hitPointsToDisplay = (double)arg;
        }
        else if (arg is int)
        {
            _scoreToDisplay = (int)arg;
        }
    }

    public void DisplayHitPoints()
    {
        Console.WriteLine("Hit Points: ");
        Console.WriteLine(_hitPointsToDisplay.ToString());
    }

    public void DisplayScore()
    {
        Console.WriteLine("Score: ");
        Console.WriteLine(_scoreToDisplay.ToString());
    }
}

Now we just need to modify the concrete subject, our Player class, to correctly notify its observers.
public class Player : ISubject
{
    //Here's some data that needs to be observed.
    double _hitPoints = 20d;
    int _score = 0;

    //We need a collection of observers to notify.
    List<IObserver> _observers = new List<IObserver>();

    //Here's the method that actually changes the hitpoints.
    public void TakeDamage(double damageTaken)
    {
        _hitPoints -= damageTaken;
        //Once this field has been altered, we automatically notify its observers.
        NotifyObservers(_hitPoints);
    }

    //This method adds to the player's score.
    public void AddScore(int score)
    {
        _score += score;
        //And again, we notify observers.
        NotifyObservers(_score);
    }

    public void RegisterObserver(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void UnregisterObserver(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void NotifyObservers(object arg)
    {
        //Here we simply iterate through each registered observer and pass each one
        //the current hitpoints.
        foreach (IObserver observer in _observers)
        {
            observer.Update(arg);
        }
    }
}

I've done away with the StateChanged() method and now simply call NotifyObservers(arg) with the appropriate piece of data.

One thing to notice is that the Subject decides what data gets passed to the observers via the Update method. This is called the push method of notification since the Subject pushes the data onto its observers. This may not always be what we want. There may be an observer that's interested in some of the data its subject has but not all of it. Another method, called the pull method, allows the observers to pick and choose which data to take from its subject. Implementing it is not difficult and requires only a few changes to our existing code. I have decided to make the Subject and abstract method so that it can handle the observer collection internally.
The basic idea of the pull method is that instead of passing specific pieces of data to our observers, we pass the Subject object as the Update's argument. As long as the Subject implements some way of getting its data, the observers can decide what to take from its subject and what to ignore.

First let's modify our new IObserver interface.
public interface IObserver
{
    void Update(Subject subject, object arg);
}
Now it takes a Subject object as a parameter as well. We can keep the object arg if we ever want to pass specific data.

Our Subject class is abstract and handles the collection and notification:
public abstract class Subject
{
    List<IObserver> _observers = new List<IObserver>();

    public void RegisterObserver(IObserver observer)
    {
        _observers.Add(observer);
    }

    void UnregisterObserver(IObserver observer)
    {
        _observers.Remove(observer);
    }

    public void NotifyObservers(object arg)
    {
        foreach (IObserver observer in _observers)
        {
            observer.Update(this, arg);
        }
    }

    public void NotifyObservers()
    {
        NotifyObservers(null);
    }
}
We now have two different NotifyObserver methods. One can pass a specific piece of data for an observer to deal with and the other passes null for that argument while they both pass along the Subject.

Our Player class no longer needs to handle its observer collection.
public class Player : Subject
{
    //Here's some data that needs to be observed.
    double _hitPoints = 20d;
    int _score = 0;

    //Here's the method that actually changes the hitpoints.
    public void TakeDamage(double damageTaken)
    {
        _hitPoints -= damageTaken;
        //Once this field has been altered, we automatically notify its observers.
        NotifyObservers();
    }

    //This method adds to the player's score.
    public void AddScore(int score)
    {
        _score += score;
        //And again, we notify observers.
        NotifyObservers();
    }

    public double GetHitPoints()
    {
        return _hitPoints;
    }

    public int GetScore()
    {
        return _score;
    }
}
I'm using the pull method here to show how it works but we don't have to. Just remember that the object parameter might be null and our Observers have to handle cases like this. But for this quick example I'll go ahead and assume we're simply interested in the Subject argument.
class HUD : IObserver
{
    double _hitPointsToDisplay;
    int _scoreToDisplay;

    //Here is where the observer receives its new data.
    public void Update(Subject subject, object arg)
    {
        if (subject is Player)
        {
            Player player = subject as Player;
            _hitPointsToDisplay = player.GetHitPoints();
            _scoreToDisplay = player.GetScore();
        }
    }

    public void DisplayHitPoints()
    {
        Console.WriteLine("Hit Points: ");
        Console.WriteLine(_hitPointsToDisplay.ToString());
    }

    public void DisplayScore()
    {
        Console.WriteLine("Score: ");
        Console.WriteLine(_scoreToDisplay.ToString());
    }
}
In the Update method we grab only the data we want. The subject could have many more fields but our HUD is interested only in the hit points and score.

There you have it. Three different methods of implementing the observer pattern. Each with their own advantages and drawbacks. Deciding which method to use depends on the problem at hand and personal preference. And these are by no means the only ways of doing it, the observer pattern, like most patterns can be tweaked and modified to fit your own needs.

I hope you enjoyed the article and thanks for reading!

Tuesday, November 22, 2011

The Strategy Pattern

While they can be abused in various ways, design patterns are an essential subject to become familiar with, so I'm going to dedicate the next series of articles to design patterns.

First up is the strategy pattern. This pattern is very useful for changing a class's behavior at runtime.
Let's say we have a class that implements some method. The method works great but now we'd like to inherit from that class. The method will be inherited as well and will perform the same function. Any additional class we inherit from the base class will also come with this method. But what if one of our subclass' doesn't implement that method in exactly the same way? Well we could always make the method virtual and override it so it does something else but what if we want the class to sometimes perform the method normally and sometimes do it a little different? Here we would run into some problems.

Let's take a simple example. Consider a Car class that implements a Honk() method. Every subclass of Car will have it's own specific honk sound. This is all very well and good, but what if the owner wants to change the honk sound? What if the owner is a bit eccentric and decides they want a different sound for each day of the week? This quickly becomes a maintenance nightmare.

A way around this is to create an interface or an abstract class containing a method stub for Honk behavior. The interface is meant to encapsulate honking. Any concrete strategy class that inherits from the honking interface can implement its Honk method however it wants. The Car class, in turn, will contain a reference to a honking strategy object. When the Car calls its honking method, the strategy's method is called.
This allows for some flexible car honking behavior because now we can write methods to change one Honk interface for another. During runtime a car object can change how it honks!

These abstract behavior classes are called strategies.

Before we get into the code, let's take a quick look at the UML diagram for this pattern. You can skip over this image if you're not familiar with UML as it isn't necessary to follow the article. It can also serve as a handy reference for later.


Our Honk strategy would look something like this:
public interface IHonk
{
    void Honk();
}

Now we can inherit from this interface to make specific honks. We'll make a few here now, a NormalHonk, BrokenHonk, and a GodFatherThemeHonk.
public class NormalHonk : IHonk
{
    public void Honk()
    {
        Console.WriteLine("Honk!");
    }
}

public class BrokenHonk : IHonk
{
    public void Honk()
    {
        Console.WriteLine("fffffffff......");
    }
}

public class GodFatherThemeHonk : IHonk
{
    public void Honk()
    {
        Console.WriteLine("**mandolin music**");
    }
}

Our car class needs a reference to an IHonk object. The car's PerformHonk() method will call the Honk() method from the strategies reference.
public class Car
{
    IHonk _honkStrategy = new NormalHonk();
    
    public void PerformHonk()
    {
        _honkStrategy.Honk();
    }

    public void SetHonkStrategy(IHonk honkStrategy)
    {
        _honkStrategy = honkStrategy;
    }
}

Each car object is initialized with a NormalHonk but we can change this at any time.
Let's create a few cars and see how this works in action
class Program
{
    static void Main(string[] args)
    {
        //Here we initialize a new car, leaving it's honk strategy
        //at its default.
        Car _honda = new Car();
        
        //Here we'll make a car and set it's honk to something else.
        Car _elCamino = new Car();
        _elCamino.SetHonkStrategy(new GodFatherThemeHonk());

        //Each car has it's own honking behavior...
        _honda.Honk();
        _elCamino.Honk();

        //The Honda's horn breaks!
        _honda.SetHonkStrategy(new BrokenHonk());
        
        _honda.Honk();

        Console.ReadLine();
    }
}

We would also, ideally, make the Car class abstract and inherit from it.
public abstract class Car
{
    IHonk _honkStrategy;
    
    public void PerformHonk()
    {
        _honkStrategy.Honk();
    }

    public void SetHonkStrategy(IHonk honkStrategy)
    {
        _honkStrategy = honkStrategy;
    }
}

public class Honda : Car
{
    public Honda()
    {
        SetHonkStrategy(new NormalHonk());
    }
}

public class ElCamino : Car
{
    public ElCamino()
    {
        SetHonkStrategy(new GodFatherThemeHonk());
    }
}
And our Program class becomes simpler.
class Program
{
    static void Main(string[] args)
    {
        Car _honda = new Honda();
        
        Car _elCamino = new ElCamino();
        
        //Each car has it's own honking behavior...
        _honda.Honk();
        _elCamino.Honk();

        //The Honda's horn breaks!
        _honda.SetHonkStrategy(new BrokenHonk());
        
        //The El Camino's owner wants a normal honk.
        _elCamino.SetHonkStrategy(new NormalHonk());
        
        _honda.Honk();
        _elCamino.Honk();

        Console.ReadLine();
    }
}
And that's the Strategy Pattern. It's very simple but extremely effective at changing behavior during runtime.
Thanks for reading and I hope this was an enlightening look at the Strategy Pattern!