Factory Method And Abstract Factory Design Patterns ✨

Server Tombak
nacressoftware
Published in
5 min readMar 23, 2024

Hello everyone, design patterns serve as invaluable blueprints for solving recurring problems. In this article we'll delve into two creational design patterns: the Factory Method and the Abstract Factory. If you haven’t read my previous article on the Strategy Design Pattern, you can read it here.

Today, our focus is on understanding how the Factory Method and Abstract Factory patterns streamline the creation of objects in software systems. These patterns play a crucial role in maintaining code flexibility, scalability, and ease of maintenance, making them essential tools in a developer's arsenal. Let’s learn more about these two creational design pattern.

What are they and What is the difference?

They are both similar the difference is that Factory method is creating objects of one single type but Abstract Factocry can create objects of multiple types. A real life example could be that: lets assume we have a Fast Food brand which sells veggie and cheese burger. And we can have more than one restaurants to sell it. Each restaurant will be cooking on their own veggie and cheese burger cooking style we can do that with Factory method but if the restaurants start to sells pizza too then Abstract Factory is the pattern that we need because in the first scenario we had one single type (which was burger) but now we are selling pizza too there is more than one related object types anymore.

Let’s start to learn from Factory Method it will make easier to see the difference between them and also make easier to understand Abstract Factory.

Factory Method✨

It helps us to handle creation of similar objects. I don’t want to make explanation here because I am doing that with in the code example 👇

Let’s code our scenario

We will be selling two different burger types Veggie and Cheese burger. So we will create an interface for burger and two classes which will be Veggie and cheese burger.

interface IBurger
{
void CookBurger();
}
class CheeseBurger : IBurger
{
public void CookBurger()
{
Console.WriteLine("Cooking a Cheese Burger");
}
}
class VeggieBurger : IBurger
{
public void CookBurger()
{
Console.WriteLine("Cooking a veggie Burger");
}
}

In this code snippet we have completed our burger types and now we will create BurgerFactory abstract class which will be the factory and we will use it to create burgers :)

abstract class BurgerFactory
{
public abstract IBurger MakeBurger(string type);

public IBurger OrderBurger(string type)
{
IBurger burger = MakeBurger(type);
burger.CookBurger();
return burger;
}
}

And now we have the factory and I want to give a quick brief about it. The factory makes things easier because we had two different kind of burger and we will have restaurants which will implement that factory and they will be able to make this two burgers too. And even if we wanted we could let them to make burger on their own way. still they would be able to cook two different burger types we could make CookBurger(parameters(like cheese etc)) method to take parameters like how much cheese to use in Cheese burger. They would be able to decide that. Its all about the scenarios and your needs.

And if we want to make another burger types too for selling we will be able to give that functionality quite easily because we will not need to make any changes in Factory and in our written code. we will just create a new class and this class will be implementing IBurger interface. And the factory could be able to create this new type too. That’s a good example of SOLİD’s Open Closed principle.

Now lets go on and make some restaurants and makes Burger to eat :)

class RestaurantA : BurgerFactory
{
public override IBurger MakeBurger(string type)
{
Console.WriteLine("Cooking on RestaurantA");
if (type.ToLower() == "veggie")
{
return new VeggieBurger();
}
return new CheeseBurger();
}
}


class RestaurantB : BurgerFactory
{
public override IBurger MakeBurger(string type)
{
Console.WriteLine("Cooking on RestaurantB");
if (type.ToLower() == "veggie")
{
return new VeggieBurger();
}
return new CheeseBurger();
}
}

We have Restaurants too now lets eat in these restaurants. I mean call the methods 👯

// Eating on Reasturan A
BurgerFactory restaurantA = new RestaurantA();
restaurantA.OrderBurger("veggie");


// Eating on Restaurant B
BurgerFactory restaurantB = new RestaurantB();
restaurantB.OrderBurger("Chees");

I hope the explanation was clear for Factory Method now let’s see Abstract Factory Design Pattern

Abstract Factory✨

Abstract Factory Design Pattern: as we say before the difference is that it helps us to organize a group of related classes.

In our example we had restaurants which makes burgers now lets start to sell Pizza too. When we do that we need to use Abstract Factory Design pattern because now we have more than one fast food product

We still have same burger types so we will create an interface for Pizza. And we will make just Margherita pizza for now.

interface IPizza
{
void CookPizza();
}

class Margheritapizza: IPizza
{
public void CookPizza()
{
Console.WriteLine("Cooking a Margherita Pizza");
}
}

Now we have pizza type too. And its time to handle factory. As you remember we already can make burger now we should add there making pizza functionality. And I will change the name of factory from BurgerFactory to → RestaurantFactory because now our restaurant is not just cooking burger that’s why a general name will be better :)

//Factory name updated to RestaurantFactory
abstract class RestaurantFactory
{
public abstract IBurger MakeBurger(string type);
public abstract IPizza MakePizza();

public IPizza OrderPizza()
{
IPizza pizza = MakePizza();
pizza.CookPizza();
return pizza;
}

public IBurger OrderBurger(string type)
{
IBurger burger = MakeBurger(type);
burger.CookBurger();
return burger;
}
}

now our factory has functionality for ordering pizza too. And its time to add make implementations on Restaurant classes

class RestaurantA : RestaurantFactory
{
public override IBurger MakeBurger(string type)
{
Console.WriteLine("Cooking on RestaurantA");
if (type.ToLower() == "veggie")
{
return new VeggieBurger();
}
return new CheeseBurger();
}

public override IPizza MakePizza()
{
Console.WriteLine("Cooking on RestaurantA");
return new Margheritapizza();
}
}


class RestaurantB : RestaurantFactory
{
public override IBurger MakeBurger(string type)
{
Console.WriteLine("Cooking on RestaurantB");
if (type.ToLower() == "veggie")
{
return new VeggieBurger();
}
return new CheeseBurger();
}

public override IPizza MakePizza()
{
Console.WriteLine("Cooking on RestaurantB");
return new Margheritapizza();
}
}

We have completed the implementation too. Our Abstract Factory have ability to make multiple type fast food burger and pizza.

Let’s order pizza and burger in both restaurant.

RestaurantFactory restaurantA = new RestaurantA();
restaurantA.OrderBurger("veggie");
restaurantA.OrderPizza();


// Eating on Restaurant B
RestaurantFactory restaurantB = new RestaurantB();
restaurantB.OrderBurger("veggie");
restaurantB.OrderPizza();

So that was all I wanted to write on that article. You can access the source code from here.

Don’t forget to claps and follow to hear more from us. Happy coding :)

--

--

Server Tombak
nacressoftware

Software Engineer with a relentless passion for learning and sharing knowledge. Join me on my journey to explore the ever-evolving world of technology.