Click here to Skip to main content
15,905,508 members
Articles / Programming Languages / C#

Abstract Factory Design Pattern with simple C# example

Rate me:
Please Sign up or sign in to vote.
1.55/5 (3 votes)
15 Jul 2018CPOL3 min read 16.7K   4   1
This article covers a basic overview of Abstract Factory design pattern with one example in C#

Overview

We often talk about design patterns and their implementations in our applications. As you know that the design patterns have three categories named creational, structural and behavioral respectively.  Abstract Factory is one of the key patterns and it falls under the creational segment. I know there are many articles available for Abstract Factory Pattern but my goal is to explain this concept with a simple and real-world example.

 

Simple words definition:

It is a creational design pattern which provides an interface for creating families of related objects without specifying their concrete types.               

Now, what it does mean? It means when you have a whole bunch of related classes and you want to create their objects together and let their factory decide which product needs to be created, it is called the Abstract Factory Pattern.

 

Why Abstract Factory?

So far we understood the basic information but we must think that why do we need to implement this design pattern? Let me explain this by giving a simple example. Let’s assume there is a car manufacturing factory and it manufactures different segments of the cars. It produces mini and compact Sedans and also SUV’s. The factory must be having separate units of manufacturing these vehicles. The problem occurs when the manufacturing company doesn’t want to manufacture compact and full cars together. So here Abstract Factory comes into the picture. Manufacturing units should not directly manufacture the cars, it should prepare and instantiate the car through a factory and this factory tells them that what type of car needs to be manufactured.

 

Example

Before seeing the example, you must know five main components of the Abstract Factory design pattern. they are as follows:

Abstract Factory: An abstract container which creates abstract products.

Concrete Factory: It implements an abstract container to create concrete products.

Abstract Product: It is an interface tells us which type of product needs to be created.

Concrete Product: The real world product by referring related abstract product.

Client: This guy creates families of related objects to create the actual product out of the factory.

 

Now, I am going to implement the same Abstract Car Factory as an example. First I am creating an interface which will be our abstract factory for producing cars. This abstract factory is implemented by Honda and Toyota factories to manufacture different types of cars. We will build client as well to decide which car needs to be manufactured. Let’s begin coding.

 

Abstract Factory:

This interface is our abstract car factory:

C++
public interface ICarFactory
{
    ISedan ManufactureSedan(string segment);
    ISuv ManufactureSuv(string segment);
}

 

Concrete Factory:

These classes are concrete factories for HONDA and TOYOTA which implement the abstract factory to manufacture cars:

C++
public class HondaFactory : ICarFactory
{
    public ISedan ManufactureSedan(string segment)
    {
        switch (segment)
        {
            case "compact":
                return new HondaCompactSedan();
            case "full":
                return new HondaFullSedan();
            default:
                throw new Exception();
        }
    }

    public ISuv ManufactureSuv(string segment)
    {
        switch (segment)
        {
            case "compact":
                return new HondaCompactSuv();
            case "full":
                return new HondaFullSuv();
            default:
                throw new Exception();
        }
    }
}



public class ToyotaFactory : ICarFactory
{
    public ISedan ManufactureSedan(string segment)
    {
        switch (segment)
        {
            case "compact":
                return new ToyotaCompactSedan();
            case "full":
                return new ToyotaFullSedan();
            default:
                throw new Exception();
        }
    }

    public ISuv ManufactureSuv(string segment)
    {
        switch (segment)
        {
            case "compact":
                return new ToyotaCompactSuv();
            case "full":
                return new ToyotaFullSuv();
            default:
                throw new Exception();
        }
    }
}

 

Abstract Products:

Below interfaces are abstract products for manufacturing Sedan and SUV:

C++
//abstract product A
public interface  ISedan
{
    string Name();
}

//abstract product B

public interface  ISuv
{
    string Name();
}

 

Concrete Products:

Here we have actual products. These classes are used to create actual products by following their abstract products

C++
//concrete product X1
public class HondaCompactSedan : ISedan
{
    public string Name()
    {
        return "Honda Amaze";
    }
}

//concrete product X2
public class HondaFullSedan : ISedan
{
    public string Name()
    {
        return "Honda Accord";
    }
}

//concrete product Y1
public class HondaCompactSuv : ISuv
{
    public string Name()
    {
        return "Honda CR-V";
    }
}

//concrete product Y2
public class HondaFullSuv : ISuv
{
    public string Name()
    {
        return "Honda Pilot";
    }
}

//concrete product X11
public class ToyotaCompactSedan : ISedan
{
    public string Name()
    {
        return "Toyota Yaris";
    }
}

//concrete product X12
public class ToyotaFullSedan : ISedan
{
    public string Name()
    {
        return "Toyota Camry";
    }
}

//concrete product Y11
public class ToyotaCompactSuv : ISuv
{
    public string Name()
    {
        return "Toyota Rav-4";
    }
}

//concrete product Y12
public class ToyotaFullSuv : ISuv
{
    public string Name()
    {
        return "Toyota Highlander";
    }
}

 

Abstract Factory Client:

Now let’s go ahead and create a client to manufacture cars by following this abstract factory

C++
public class CarClient
{
    private ISedan sedan;
    private ISuv suv;

    public CarClient(ICarFactory factory, string segment)
    {
        sedan = factory.ManufactureSedan(segment);
        suv = factory.ManufactureSuv(segment);
    }

    public string GetManufacturedSedanName()
    {
        return sedan.Name();
    }

    public string GetManufacturedSuvName()
    {
        return suv.Name();
    }

}

 

Main method (to show manufactured car details):

This code segment is instantiating car client by passing the corresponding concrete factory and segment in a parameterized constructor to let factory know that which car needs to be manufactured. If you see now, we are creating families of related objects (Honda and Toyota factories) without specifying their concrete types (e.g. Honda CR-V, Toyota Camry etc.)

C++
static void Main(string[] args)
{
    CarClient hondaClient;
    CarClient toyotaClient;
    Console.WriteLine("\r\n------------This is HONDA Car Factory----------------");
    hondaClient = new CarClient(new HondaFactory(), "compact");
    Console.WriteLine("\r\n Manufactureing " + hondaClient.GetManufacturedSedanName() + " as compact Sedan");
    Console.WriteLine("\r\n Manufactureing " + hondaClient.GetManufacturedSuvName() + " as compact SUV");

    hondaClient = new CarClient(new HondaFactory(), "full");
    Console.WriteLine("\r\n Manufactureing " + hondaClient.GetManufacturedSedanName() + " as full Sedan");
    Console.WriteLine("\r\n Manufactureing "+ hondaClient.GetManufacturedSuvName() + " as full SUV");

    Console.WriteLine("\r\n\r\n------------This is TOYOTA Car Factory----------------");
    toyotaClient = new CarClient(new ToyotaFactory(), "compact");
    Console.WriteLine("\r\n Manufactureing " + toyotaClient.GetManufacturedSedanName() + " as compact Sedan");
    Console.WriteLine("\r\n Manufactureing " + toyotaClient.GetManufacturedSuvName() + " as compact SUV");

    toyotaClient = new CarClient(new ToyotaFactory(), "full");
    Console.WriteLine("\r\n Manufactureing " + toyotaClient.GetManufacturedSedanName() + " as full Sedan");
    Console.WriteLine("\r\n Manufactureing "+ toyotaClient.GetManufacturedSuvName() + " as full SUV");
    Console.ReadLine();
}

 

Results:

It’s time now to see how this abstract factory is producing the cars. Here you go:

result-console.PNG

Conclusion

I hope this article will give you a basic idea of Abstract Factory pattern and help in your development. As I mentioned earlier that there are many article and videos available for this topic across the web but I thought I could explain this with a day to day life product example. Abstract factory is very important and used in most of the enterprise level application development.

I will look forward to your valuable feedback and suggestions. Also please let me know if I forgot anything in this article.

 

Thanks for your valuable time reading my article and good luck!

 

Atul Dongare

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Working in the United States as a senior full-stack .Net developer.

Comments and Discussions

 
QuestionQuestion Pin
Vikas K Gupta15-Jul-18 23:23
Vikas K Gupta15-Jul-18 23:23 
Hi, What if a factory demands to produce SUV car only not the sedan, can this pattern be used in that scenario?
VK Writes.............

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.