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

Factory Pattern — C#

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

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.

Похожее
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...
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...
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...
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...
Написать сообщение
Тип
Почта
Имя
*Сообщение
RSS
Если вам понравился этот сайт и вы хотите меня поддержать, вы можете
Soft skills: 18 самых важных навыков, которыми должен владеть каждый работник
Почему хорошие разработчики пишут плохие юнит-тесты
Angular или React: что выбрать в 2023 году?
10 продвинутых способов писать в консоль помимо console.log
Функции и хранимые процедуры в PostgreSQL: зачем нужны и как применять в реальных примерах
14 вопросов об индексах в SQL Server, которые вы стеснялись задать
Проблема понимания существующего кода, или Как делать иногда [не] надо
Правило 3-х часов: сколько нужно работать в день
Переход от монолита к микросервисам: история и практика
Стили именования переменных и функций. Используйте их все
LinkedIn: Sergey Drozdov
Boosty
Donate to support the project
GitHub account
GitHub profile