Factory Method - Design Pattern

Factory Method - Design Pattern

Software Architecture Simplified

Jul 1, 2022ยท

3 min read

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 ๐ŸŽฒ

github.com/VictorLins/DesignPatterns

Did you find this article valuable?

Support Victor Lins by becoming a sponsor. Any amount is appreciated!

ย