Skip to main content

Command Palette

Search for a command to run...

Factory Method - Design Pattern

Software Architecture Simplified

Published
3 min readView as Markdown
Factory Method - Design Pattern
V

I am a software engineer with over 10 years of experience in a huge variety of projects and architectures, some simple others considerably complex.

Some of my main skills include Software Architecture, Web Development, ASP.NET Core, React.js, Entity Framework Core, Javascript, SQL and Web Services.

I consider myself passionate about coding as I really fell excited about learning technologies and using them to automate and improve processes.

Objective 🎯

Define an interface for creating an object, letting to the subclasses (a.k.a. factory) decide which class (a.k.a. product) will instantiate, by doing this, it will remove the client’s dependency on concrete classes making it unaware of the object instantiation.

image.png

Notes 📝

  • Allows to create an instance based on the inputs provided.
  • Allows to handle multiple factories.
  • Objects returned by a factory method are often referred to as products.
  • Products must also implement an abstract class or interface.

Type

Behavioral: Describes how objects interact/communicate between themselves.

✔️Creational: Describes how to instantiate an object without large and complex.

Structural: Describes how objects/classes are composed to form larger structures.

UML 📐

image.png

Participants 🔗

• IProduct:

  • Defines the interface of the objects that will be handled by the factory.

• ProductA, ProductB:

  • Implements the IProduct interface.

• IFactory:

  • Defines the Factory Method that will return a concrete implementation of the interface IProduct.

• FactoryA, FactoryB:

  • Implements the IProduct interface
  • Implements the Factory Method to return an instance of a concrete class of IProduct.

Sample Code 🎮

Structural Example 🏛️

image.png

public static class FactoryMethodStructural
    {
        public static void Execute()
        {
            IFactory lFactory = new FactoryA();
            IProduct lProduct = lFactory.FactoryMethod("One");
            lProduct.MethodTest();
            lProduct = lFactory.FactoryMethod("Two");
            lProduct.MethodTest();

            lFactory = new FactoryB();
            lProduct = lFactory.FactoryMethod("One");
            lProduct.MethodTest();
            lProduct = lFactory.FactoryMethod("Two");
            lProduct.MethodTest();
        }
    }

    public interface IProduct
    {
        void MethodTest();
    }

    public class ProductAOne : IProduct
    {
        public void MethodTest() { Console.WriteLine("Product A One - Executing MethodTest"); }
    }

    public class ProductATwo : IProduct
    {
        public void MethodTest() { Console.WriteLine("Product A Two - Executing MethodTest"); }
    }

    public class ProductBOne : IProduct
    {
        public void MethodTest() { Console.WriteLine("Product B One - Executing MethodTest"); }
    }

    public class ProductBTwo : IProduct
    {
        public void MethodTest() { Console.WriteLine("Product B Two - Executing MethodTest"); }
    }

    public interface IFactory
    {
        IProduct FactoryMethod(String prType);
    }

    public class FactoryA : IFactory
    {
        public IProduct FactoryMethod(String prType)
        {
            if (prType == "One")
                return new ProductAOne();
            else
                return new ProductATwo();
        }
    }

    public class FactoryB : IFactory
    {
        public IProduct FactoryMethod(String prType)
        {
            if (prType == "One")
                return new ProductBOne();
            else
                return new ProductBTwo();
        }
    }

Output

image.png

Real-world Example 🔥

image.png

public static class FactoryMethodPractical
    {
        public static void Execute()
        {
            ICellphoneFactory lCellphoneFactory = new SamsungFactory();
            ICellphone lCellphone = lCellphoneFactory.GetCellphone("GalaxyS22");
            Console.WriteLine(lCellphone.GetReleasedYear());
            lCellphone = lCellphoneFactory.GetCellphone("GalaxyS20");
            Console.WriteLine(lCellphone.GetReleasedYear());

            lCellphoneFactory = new IPhoneFactory();
            lCellphone = lCellphoneFactory.GetCellphone("IPhone13");
            Console.WriteLine(lCellphone.GetReleasedYear());
            lCellphone = lCellphoneFactory.GetCellphone("IPhone12");
            Console.WriteLine(lCellphone.GetReleasedYear());
        }
    }

    public interface ICellphone
    {
        string GetReleasedYear();
    }

    public class GalaxyS22 : ICellphone
    {
        public string GetReleasedYear() { return "GalaxyS22 - Released Year: 2022"; }
    }

    public class GalaxyS20 : ICellphone
    {
        public string GetReleasedYear() { return "GalaxyS20 - Released Year: 2020"; }
    }

    public class IPhone13 : ICellphone
    {
        public string GetReleasedYear() { return "IPhone13 - Released Year: 2021"; }
    }

    public class IPhone12 : ICellphone
    {
        public string GetReleasedYear() { return "IPhone12 - Released Year: 2020"; }
    }

    public interface ICellphoneFactory
    {
        ICellphone GetCellphone(string prModel);
    }

    public class SamsungFactory : ICellphoneFactory
    {
        public ICellphone GetCellphone(string prModel)
        {
            if (prModel == "GalaxyS22")
                return new GalaxyS22();
            else
                return new GalaxyS20();
        }
    }

    public class IPhoneFactory : ICellphoneFactory
    {
        public ICellphone GetCellphone(string prModel)
        {
            if (prModel == "IPhone13")
                return new IPhone13();
            else
                return new IPhone12();
        }
    }

Output

image.png

Source Code 🎲

https://github.com/VictorLins/DesignPatterns