Поиск  
Always will be ready notify the world about expectations as easy as possible: job change page
Jan 31

Factory Pattern — C#

Factory Pattern — C#
Автор:
Источник:
Просмотров:
1983

This is a creational pattern that provides a way to create an object without exposing the creation logic for the users of it. There are two well-known approaches that I will explain and show how and when you should use them.

Abstract Factory

This type of factory creates families of objects that are related to each other without specifying their concrete classes.

Example

Let’s say that we have a burger industry and we are able to create beef burgers and vegetarian burgers. The main idea is to have multiple clients that use my factory to create their burgers to sell them in their restaurants or markets.

The abstraction of BurgerFactory with two implementations
The abstraction of BurgerFactory with two implementations

To create a beef burger they need to specify the fat percentage that will exist in the composition of the burger. For the vegetarian ones, they need to define the base vegetable that will be used to create them. These two requirements are part of our factory interface IBurgerFactory.

The abstraction of Beef and Vegetarian Burger
The abstraction of Beef and Vegetarian Burger

We have our first client! A low cost burger company contact us to produce their burgers. The first thing is to define the specific classes that implement the previous interfaces.

public class LowCostVegetarianBurger : IVegetarianBurger
{
    public string GetBaseVegetable() => "Chickpea";
}

public class LowCostBeefBurger : IBeefBurger
{
    public int GetFatPercentage() => 5;
}

Now we need to create the concrete factory that implements the required interface.

public class LowCostBurgerFactory : IBurgerFactory
{
    public LowCostBurgerFactory()
    {
    }

    public IBeefBurger CreateBeefBurger()
    {
        return new LowCostBeefBurger();
    }

    public IVegetarianBurger CreateVegetarianBurger()
    {
        return new LowCostVegetarianBurger();
    }
}

What if I don’t want some type of burger?

Just return null or an exception if you prefer. However, if this is a recurrent situation I advise you to create two different interfaces. One just for beef burger factories and another for vegetarian burgers factories. You will have IBeefBurgerFactory and IVegetarianBurgerFactory instead of IBurgerFactory.

How can use it?

IBurgerFactory lowCostFactory = new LowCostBurgerFactory();
_logger.LogInformation($"Beef Burger fat percentage: {lowCostFactory.CreateBeefBurger().GetFatPercentage()}");
_logger.LogInformation($"Vegetarian Burger base: {lowCostFactory.CreateVegetarianBurger().GetBaseVegetable()}");

This is a simple example to understand the purpose of this factory approach. You will certainly add more complexity to the creation of your objects.

Factory Method

This type of factory gives an interface to create objects in a superclass. However, allows that the subclasses decide the type of objects that will be created.

Example

We received a request from a mobile application that manages orders to restaurants. This app needs to show the restaurant menu to its users.
Let’s create a factory to be inherited by any restaurant in order to create their menus.
The most important thing to do is to define an abstract class that has a GetMenu() method. This will be our factory method.

The abstract class MenuFactory with two implementations
The abstract class MenuFactory with two implementations

Every restaurant factory must extend this class and implement the abstract method. Having a main abstract factory allows us to provide other methods to be used by any child class, the method GetPrice() has that purpose.

public abstract class MenuFactory
{
    public abstract Menu GetMenu();
    
    public float GetPrice(string itemName)
    {
        Menu menu = GetMenu();
        MenuItem menuItem = menu.Items.SingleOrDefault(m => m.Name == itemName);
        if (menuItem != null)
            return menuItem.Price;

        return 0;
    }
}

The following code block shows an example of a restaurant factory.

public class BurgerRestaurantFactory : MenuFactory
{
    private readonly string _restaurantName;

    public BurgerRestaurantFactory()
    {
        _restaurantName = "Burger Shot";
    }

    public override Menu GetMenu()
    {
        List<MenuItem> menuItems = new List<MenuItem>()
        {
            new MenuItem("Smash Burger", 3),
            new MenuItem("Cheese Burger", 4),
            new MenuItem("Bacon Cheese Burger", 5.49f),
            new MenuItem("Smash Burger Combo", 5.99f)
        };

        return new Menu(_restaurantName, menuItems);
    }
}

This is a simple example, this burger restaurant doesn’t add anything besides the menu and its name. However, we know that this class can be, and probably will, more complex than this.

How can use it?

MenuFactory burgerRestaurantFactory = new BurgerRestaurantFactory();
Menu burgerMenu = burgerRestaurantFactory.GetMenu();string itemName = "Bacon Cheese Burger";
float baconCheesePrice = burgerRestaurantFactory.GetPrice(itemName);
_logger.LogInformation($"The restaurant {burgerMenu.RestaurantName} has a {itemName} for {baconCheesePrice}.");

You can get the menu from that restaurant and use the method to get the price of some specific item.

Conclusion

This pattern is really good to have in your hand when you want to develop any type of system. Its focus is on the creation of more complex objects where you have to create multiple other objects that compose it. The two approaches that were presented are equally good options, you just need to understand the differences and choose the one that better fits your necessities.
Besides all that was said and explained I just need to add one thing: Yes I love burgers.

Похожее
May 27, 2023
Author: Gustavo Restani
In today’s fast-paced world of software development, it is crucial to be familiar with design patterns that can help you create robust, efficient, and maintainable code. One of the most widely used programming frameworks for enterprise applications is the .NET...
Oct 26, 2023
Author: Genny Allcroft
Key strategic and tactical considerations to take when building a new product with the domain-driven design concepts in mind I have just finished reading Learning Domain-Driven Design by Vlad Khononov. It’s quite a short book (c. 300 pages) aiming to...
Jan 13, 2023
Author: Jaydeep Patil
We are going to discuss the Unit of Work design pattern with the help of a generic repository and step-by-step implementation using .NET Core 6 Web API. Agenda Repository Pattern Unit of Work Step-by-step Implementation Prerequisites Visual Studio 2022 SQL...
Aug 2
Author: Amit Verma
In-depth overview of 18 essential Software Architecture design patterns. Table of contents What is Software Architecture? Why do we need software architecture? Software Architecture vs Software Design How to document architecture? 4C model 18 Software Architecture design patterns to know...
Написать сообщение
Тип
Почта
Имя
*Сообщение