Design Patterns – Strategy vs Factory Design Pattern

cdesign-patternsfactory-methodstrategy-pattern

I am new to design patterns and working my way through the Factory Method and Strategy patterns. I understand that Factory is a creational pattern and Strategy is behavioral but I struggle to understand when to use which one. For example, I have the following classes that updates client details based on the company specified:

    public interface IUpdateDetails { void UpdateDetails(); }

    public class UPSUpdateDetails : IUpdateDetails
    {
        public void UpdateDetails() => Console.WriteLine("Call web service to update details for UPS...");
    }

    public class FedExUpdateDetails : IUpdateDetails
    {
        public void UpdateDetails() => Console.WriteLine("Update database for FedEx...");
    }

    public class DHLUpdateDetails : IUpdateDetails
    {
        public void UpdateDetails() => Console.WriteLine("Send Email for DHL...");
    }

I can create a Factory to return the correct class:

    public class UpdateDetailsFactory
    {
        public static IUpdateDetails Create(string type)
        {
            switch (type)
            {
                case "UPS":
                    return new UPSUpdateDetails();
                case "DHL":
                    return new DHLUpdateDetails();
                case "FedEx":
                    return new FedExUpdateDetails();
                default:
                    throw new ArgumentException();
            }
        }
    }

and implement it as follows:

    // Using Factory
    string company = "UPS"; // Get company from database
    IUpdateDetails updateDetails = UpdateDetailsFactory.Create(company);
    updateDetails.UpdateDetails();
    Console.ReadLine();

or I can use the Strategy pattern:

    public class UpdateDetailsContext
    {
        private IUpdateDetails strategy;

        public void SetStrategy(IUpdateDetails updateDetails) => strategy = updateDetails;

        public void Update() => strategy.UpdateDetails();
    }

and implement it as follows:

    // Using Strategy
    UpdateDetailsContext context = new UpdateDetailsContext();
    context.SetStrategy(UpdateDetailsFactory.Create(company));
    context.Update();
    Console.ReadLine();

My question is – am I understanding the patterns correctly? What is the difference between using the one over the other?

Best Answer

You are correct that these have a lot of similarities. As mentioned in other answers, the difference is about goals.

The Strategy pattern is often misunderstood but it's also one of them most valuable patterns for simplifying code. The key to the pattern is that it allows you to have objects that change their behavior at runtime. To think of a good example of this, consider a video game where you are in some sort of battle with a non-player enemy. At some point, when you have reduced the enemy's 'health' to a certain level, the enemy will change from a 'fight' to a 'flight' mode. Now, you could put a bazillion if statements all over the place to check which mode it's in but that's a huge mess. Instead, you use a strategy pattern and have a set of different behavior definitions represented as objects. Depending on the 'health' level, the correct behavior is used.

This doesn't just apply to video games. Let's say you have an ordering system and you've been given requirements to fall back to a secondary cloud provider (more expensive but more reliable, let's say.) You could use the strategy pattern to keep that sane.

The factory method pattern is a nice replacement for a constructor. A great example of this is something like an Integer factory that returns the same object every time you pass in the value 0 or 1.

The thing is that you can actually put these together in lots of interesting ways. For example, you could create a factory method that uses a strategy pattern to determine what objects to create. For example, you might use it in the above ordering system example to return a different DB connection objects depending on the circumstances.

A common saw is "patterns are descriptive, not prescriptive." In other words, these are ways to describe a design approach, not recipes. A common mistake is trying to use them like legos to build a solution.