DEV Community

Theodore Karropoulos
Theodore Karropoulos

Posted on

Factory Method Pattern

Factory method pattern is a creational design pattern that provides an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Problem
Lets imagine we are creating a pizza store and we have multiple type of pizzas we serve to our customers. At first the only pizza type our store is baking is the four cheese pizza. After a while many of our customers requests for a bigger variety of pizza and we decide to add peperoni and Greek pizzas to our menu. These are great news but what about our code?

Solution
Here is where Factory Method Pattern comes in handy. The pattern suggests that we replace any direct construction calls with calls to a factory method.

Implementation
The first thing we are going to create is the Pizza abstract class.

public abstract class Pizza
{
    public string Name { get; set; }
    public List<string> Ingredients { get; set; }
    public PizzaType Type{ get; set; }
}
Enter fullscreen mode Exit fullscreen mode

With that out of the way we are going to create our concrete classes implementing the abstract class

class FourCheesePizza : Pizza
{
    public FourCheesePizza()
    {
        Type = PizzaType.FourCheese;
        Name = "Cheese passion";
        Ingredients = new List<string> 
        {
            "Parmigiano Cheese",
            "Gorgonzola Cheese", 
            "Ricotta Cheese",
            "Taleggio Cheese",
            "Tomato" 
        };
    }
}
Enter fullscreen mode Exit fullscreen mode
class GreekPizza : Pizza
{
    public GreekPizza()
    {
        Name = "The Greek freak";
        Type = PizzaType.Greek;
        Ingredients = new List<string> 
        { 
            "Spinach", 
            "Olives", 
            "Feta Cheese", 
            "Onion", 
            "Red Peppers" 
       };
    }
}
Enter fullscreen mode Exit fullscreen mode
class PepperoniPizza : Pizza
{
    public PepperoniPizza()
    {
        Name = "Pepperoni lovers";
        Type = PizzaType.Pepperoni;
        Ingredients = new List<string> 
        {
            "Basil", 
            "Peperoni", 
            "Garlic", 
            "Tomato", 
            "Mozzarella Cheese" 
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

Next step is to create the actual factory interface and it’s implementation

interface IPizzaFactory
{
    Pizza CreatePizza(PizzaType type);
}

class PizzaFactory : IPizzaFactory
{
    public Pizza CreatePizza(PizzaType type)
    {
        switch (type)
        {
            case PizzaType.FourCheese:
                return new FourCheesePizza();
            case PizzaType.Pepperoni:
                return new PepperoniPizza();
            case PizzaType.Greek:
                return new GreekPizza();
            default:
                return null;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And now we can use the factory to get a pizza object by passing the pizza type information.

static void Main(string[] args)
{
    var pizza = OrderPizza(PizzaType.Greek);

    Console.WriteLine("Pizza name: " + pizza.Name);
    Console.WriteLine("---------------------");
    Console.WriteLine("Ingredients");
    Console.WriteLine("---------------------");
    Console.WriteLine(string.Join(Environment.NewLine, pizza.Ingredients));
    Console.ReadKey();
}

static Pizza OrderPizza(PizzaType type)
{
    IPizzaFactory factory = new PizzaFactory();
    return factory.CreatePizza(type);
}
Enter fullscreen mode Exit fullscreen mode

If you want to read more stories please visit my blog.

Top comments (0)