Abstract Factory Design Pattern in C# with Real-Time Example

In this article, we will discuss Abstract  Factory Design Patterns in C# with models. it is a type of Creational Design Pattern.


What is Abstract Factory Design Pattern?

According to the Gang of Four Definition: The Abstract Factory Design Pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes“.


The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes

Abstract Factory pattern belongs to creational patterns and is one of the most used design patterns in real-world applications

An abstract factory is a super factory that creates other factories

We need to Choose Abstract Factory Pattern when

  1. The application needs to create multiple families of objects or products
  2. We need to use only one of the subset of families of objects at a given point of time
  3. We want to hide the implementations of the families of products by decoupling the implementation of each of these operations
Understanding Abstract Factory Design Pattern:
Abstract Factory Representation





  1. Client is a class that uses AbstractFactory and AbstractProduct interfaces to create a family of related objects.
  2. AbstractFactory is an interface that is used to create an abstract product.
  3. ConcreteFactory is a class that implements the AbstractFactory interface to create concrete products.
  4. AbstractProduct is an interface that declares a type of product.
  5. ConcreteProduct is a class that implements the AbstractProduct interface to create a product.

Business Requirement:
 The company gifts laptops to 
Permanent and Contract employees based on the designation and employee type as per below

Permanent Employee
  • Managerial Position is eligible for Apple MAC Book Laptop
  • Non-Managerial Position is eligible for Apple iMac desktop
Contract Employee
  • Managerial Position is eligible for Dell Laptop
  • Non-Managerial Position is eligible for Dell desktop

Step 1: - To implement this functionality 1st create the enumeration class like below


   

public class Enumerations

    {

        public enum EmployeeType

        {

            Permanent,

            Contract

        }

 

        public enum JobPosition

        {

            Manager,

            NonManager

        }

        public enum ComputerTypes

        {

            Laptop,

            Desktop

        }

        public enum Brands

        {

            APPLE,

            DELL

        }

        public enum Processors

        {

            I3,

            I5,

            I7

        }

    }


!Now lets create the employee class and then define the properties to that class
Employee.cs

    public class Employee

    {

        public int Id { get; set; }

 

        public string Name { get; set; }

        public string Department { get; set; }

        public Enumerations.EmployeeType EmployeeTypeID { get; set; }

 

        public string ComputerDetails { get; set; }

 

        public Enumerations.JobPosition EmployeeJobPosition { get; set; }

    }



Step2 :- Now create the interface for Brand, processors and System Type ,like below



class BrandInterfaceFactory

    {

        public interface IBrand

        {

            string GetBrand();

        }

    }

 

    class SystemTypeInterfaceFactory

    {

        public interface ISystemType

        {

            string GetSystemType();

        }

    }

 

    class ProcessorInterfaceFactory

    {

        public interface IProcessor

        {

            string GetProcessor();

        }

 

 

    }


Step 3: After creating the interfaces , lets implement the classes and inherit from the respective interfaces, like below
 
So here we have SystemType as Laptop and desktop , so lets create it 

SystemType.cs

    public class SystemType

    {

        public class Laptop : ISystemType

        {

            public string GetSystemType()

            {

                return Enumerations.ComputerTypes.Laptop.ToString();

            }

        }

        public class Desktop : ISystemType

        {

            public string GetSystemType()

            {

                return Enumerations.ComputerTypes.Desktop.ToString();

            }

        }

    }


Now let's create brand-type classes, because we have two type of brand
BrandType.cs

    public class BrandType

    {

        public class MAC: IBrand

        {

            public string GetBrand()

            {

                return Enumerations.Brands.APPLE.ToString();

            }

        }

    }

 

    public class DELL: IBrand

    {

        public string GetBrand()

        {

            return Enumerations.Brands.DELL.ToString();

        }

    }


Now let's create a Processer Type class

ProcesserType.cs

    public class ProcesserType

    {

        public class I7 : IProcessor

        {

            public string GetProcessor()

            {

                return Enumerations.Processors.I7.ToString();

            }

        }

        public class I5 : IProcessor

        {

            public string GetProcessor()

            {

                return Enumerations.Processors.I5.ToString();

            }

        }

    }


Now let's create the ComputerFactory interface and create methods for BrandType, SystemType, and ProcessorType

ComputerFactory.cs

   public interface IComputerFactory

    {

        IBrand Brand();           

        ISystemType SystemType();

        IProcessor Processor();

    }


Now Create DellFactory.cs class and inherit it from IComputerFactory interface and give the implementation of methods

And then create the DellLaptopFactory and inherit it from the DellFactory class like below

public class DellFactory: IComputerFactory

    {

        public IBrand Brand()

        {

            return new DELL();

        }

 

        public IProcessor Processor()

        {

            return new ProcesserType.I5();

        }

 

        public virtual ISystemType SystemType()

        {

            return new SystemType.Desktop();

        }

    }

 

    public class DellLaptopFactory : DellFactory

    {

        public override ISystemType SystemType()

        {

            return new SystemType.Laptop();

        }

    }


Similar to DellLaptop Factory, create the MAC laptop factory

public class MACFactory: IComputerFactory

    {

        public IBrand Brand()

        {

            return new BrandType.MAC();

        }

 

        public IProcessor Processor()

        {

            return new ProcesserType.I7();

        }

 

        public virtual ISystemType SystemType()

        {

            return new SystemType.Desktop();

        }

    }

    public class MACLaptopFactory: MACFactory

    {

 

        public override ISystemType SystemType()

        {

            return new SystemType.Laptop();

        }

 

    }


Now let's create the employeeSystemFacory.cs class

   public class EmployeeSystemFactory

    {

        public IComputerFactory Create(Employee e)

        {

            IComputerFactory returnValue = null;

            if (e.EmployeeTypeID == Enumerations.EmployeeType.Permanent)

            {

                if (e.EmployeeJobPosition == Enumerations.JobPosition.Manager)

                {

                    returnValue = new MACLaptopFactory();

                }

                else

                {

                    returnValue = new MACFactory();

                }

            }

            else if (e.EmployeeTypeID == Enumerations.EmployeeType.Contract)

            {

                if (e.EmployeeJobPosition == Enumerations.JobPosition.Manager)

                {

                    returnValue = new DellLaptopFactory();

                }

                else

                    returnValue = new DellFactory();

            }

            return returnValue;

        }

    }


Now create the EmployeeSystemManager class

    public class EmployeeSystemManager

    {

        IComputerFactory _IComputerFactory;

        public EmployeeSystemManager(IComputerFactory iComputerFactory)

        {

            _IComputerFactory = iComputerFactory;

        }

        public string GetSystemDetails()

        {

            IBrand brand = _IComputerFactory.Brand();

            IProcessor processor = _IComputerFactory.Processor();

            ISystemType systemType = _IComputerFactory.SystemType();

 

 

            string returnValue = string.Format("{0} {1} {2}", brand.GetBrand(),

                systemType.GetSystemType(), processor.GetProcessor());

            return returnValue;

        }

    }


Now lets write the below code in the Main method

   static void Main(string[] args)

        {

            Employee emp = new Employee()

            {

                Id = 1,

                EmployeeJobPosition = Enumerations.JobPosition.Manager,

                EmployeeTypeID = Enumerations.EmployeeType.Permanent,

              

            };

 

           

            IComputerFactory factory = new EmployeeSystemFactory().Create(emp);

            EmployeeSystemManager manager = new EmployeeSystemManager(factory);

            emp.ComputerDetails = manager.GetSystemDetails();

 

            Console.WriteLine("Result :- " + emp.ComputerDetails);

            Console.ReadLine();

        }


Below is the output


Pointe to Remember:
  1. Abstract Factory Pattern provides an interface for creating families of related dependent objects without specifying their concrete classes.
  2. The Abstract Factory Pattern provides a way to encapsulate a group of individual factories that have a common theme without specifying their concrete classes.
  3. The abstract factory design pattern is merely an extension to the factory method pattern or factory pattern, which allows you to create objects without being concerned about the actual class of the object being created.
  4. Abstract means hiding some information and factory means which produces the products and pattern means a design. So, the Abstract Factory Pattern is a software design pattern that provides a way to encapsulate a group of individual factories that have a common theme.
When to use it Abstract Factory Design Pattern?

When we need to use the Abstract Factory Design Pattern in the following cases

  1. When you want to create a set of related objects or dependent objects which must be used together.
  2. When the system should configure to work with multiple families of products.
  3. When the Concrete classes should be decoupled from the clients.
Differences between Abstract Factory and Factory Method Design Pattern:
  1. Abstract Factory Design Pattern adds a layer of abstraction to the Factory Method Design Pattern
  2. The Abstract Factory design pattern implementation can have multiple factory methods
  3. Similar products of a factory implementation are grouped in the Abstract factory
  4. The Abstract Factory Pattern uses object composition to decouple applications from specific implementations
  5. The Factory Method Pattern uses inheritance to decouple applications from specific implementations
Reference:-https://csharp-video-tutorials.blogspot.com/2017/08/abstract-factory-design-pattern.html

Share this

Related Posts

Previous
Next Post »

1 comments:

Write comments