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

Factory Pattern — C#

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

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.

Похожее
Jan 1, 2023
Author: Daniel Kreider
Here’s the simple step-by-step guide that will teach you how to build and code a generic repository. There are oodles of design patterns. Some of these design patterns are floating about on antique blogs full of mad logic. They’re ridiculous...
Feb 17, 2023
Author: Juldhais Hengkyawan
A Guide to Building Scalable, Maintainable Web API using ASP .NET Core The term “Clean Architecture” has become increasingly popular in software development in recent years. Clean Architecture is a software design pattern that prioritizes the separation of concerns, making...
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...
Feb 10, 2023
Author: Hr. N Nikitins
Design patterns are essential for creating maintainable and reusable code in .NET. Whether you’re a seasoned developer or just starting out, understanding and applying these patterns can greatly improve your coding efficiency and overall development process. In this post, we’ll...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Как мы столкнулись с версионированием и осознали, что вариант «просто проставить цифры» не работает
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Проблема непонимания существующего кода, или Как руководству делать не надо
10 не самых очевидных причин, чтобы уволиться
Что такое микросервисная архитектура и когда ее применять
Программист 2020: Терминатор отдыхает
Вопросы с собеседований, которые означают не то, что вы думаете
Перестаньте называть себя программистом и другие карьерные советы
Жуткий сценарий использования ChatGPT
Рассуждение на тему, какую базу данных выбирать
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile