Abstract Factory Design Pattern in C#

What is the Abstract Factory Design Pattern?

  • Pattern denotes a design, factory denotes the location of product production, and abstract denotes the concealment of certain information. Thus, a software design pattern known as the Abstract Factory Pattern offers a means of encapsulating a collection of distinct factories that have a common theme.
  • Put more succinctly, the Abstract Factory can be thought of as a super factory that produces other factories. The Factory of Factories is another name for this Abstract Factory.
  • This means that while the concrete factory classes handle the actual object production, the Abstract Factory design pattern offers an interface for building families of linked or dependent products.
  • When a system must be independent of the creation, composition, and representation of its results, this design can be helpful.

Parts of the Pattern for an Abstract Factory:

The components of the Abstract Factory Design Pattern are as follows:

  • AbstractFactory: An interface for operations that produce abstract products is declared by the AbstractFactory. This will serve as an interface for the processes that generate objects of the Abstract Product.
  • ConcreteFactory: ConcreteFactory carries out the processes necessary to produce concrete product objects. These classes offer implementations for the interface methods as well as the Abstract Factory interface. Concrete product objects can be created with the help of these concrete classes.
  • AbstractProduct: Describes an interface for a certain kind of product object. These are going to be products' creation interfaces. In this case, we must specify the Operations that a Product ought to have. ConcreteProduct implements the AbstractProduct interface. The classes listed above carry out the Abstract Product interface.
  • Client: The client uses the interfaces declared by the AbstractFactory and AbstractProduct classes. This class will build a family of products by utilizing our Abstract Factory and Abstract Product interfaces.

Example to Understand Abstract Factory Design Pattern using C#:

Let's examine one real-world example to grasp the abstract factory design pattern better. To make the notion easy to understand, we will first create the example and then compare it with the UML diagram of the Abstract Factory Design Pattern.

One application that displays the details of the car and bike is what we wish to implement. Here, we'd like to display two different bike types-Regular and Sports-as well as the specifics of two different car types-Regular and Sports. It's important to keep in mind that cars and sports bikes are members of the same family Sports. In a similar vein, regular cars and bikes are members of the same family, regular. Keeping this in mind, let's go on and look at how we can use the C# Abstract Factory Design Pattern to do this.

Step 1: Creating Abstract Products

In order to create abstract products, we must declare interfaces. Here, we need to develop two interfaces, or abstract classes, for each abstract product type since we will be creating two different types of common objects, like cars and bikes. I'm going to make two interfaces here.

ICar.cs (ProductB_abstract)

After using ICar.cs to create an interface, copy and paste the following code. We plan to release this as our second abstract product. The Car product family should have a base interface for each unique product. In this instance, the ICar interface needs to be implemented by both the SportsCar and RegularCar versions of the Car products. As you can see, we have developed the following interface, which the ICar interface's subclasses will implement. It has one abstract method.

Step 2: Creating Concrete Products

The concrete product object that the relevant concrete factory will produce needs to be defined in this situation. When we talk about the concrete factory component later in the tutorial, we'll talk about how the factory produces the product object. Keep in mind that the Abstract Product Interface needs to be implemented by the concrete product classes. The IBike or ICar interface needs to be implemented by the concrete product class in our example. Thus, let's make four concrete products-RegularCar, SportsCar, RegularBike, and SportsBike-in accordance with our specifications.

RegularBike.cs (ProductA1)

After creating a class file called RegularBike.cs, could you insert the following code into it? The Bike product family includes the following regular bike products. It offers the implementation for the GetDetails method and, as you can see, implements the IBike interface.

RegularCar.cs (ProductA2)

Copy and paste the code below into a class file called RegularCar.cs. The Car product family includes the following RegularCar products. It provides implementations for the GetDetails method and implements the ICar interface, as you can see.

SportsCar.cs (ProductB2)

Please put the following code in a class file called SportsCar.cs by copying and pasting it. The Car product family includes the sports car listed below. It provides implementations for the GetDetails method and implements the ICar interface, as you can see.

Step 3: Creating Abstract Factory

In this case, an interface for the operations that generate AbstractProduct objects must be created. It is going to be IVehicleFactory in our example. Hence, copy and paste the following into a class file called IVehicleFactory.cs. Two methods are included in this class, as you can see. While the CreateCar function creates several car versions, the CreateBike method creates various bike variants. It's important to keep in mind that, in this case, we are merely declaring the methods and returning the type of these two methods, which are the abstract products, ICar and IBike. As a result, we can generate various objects (i.e., objects of ICar and IBike subclasses) from the child classes.

NOTE: The abstract factory class mentioned above creates a family of other factories. Let's move on and establish this kind of factory family.

Step 4: Creating Concrete Factories

In order to construct concrete product objects, we must now create concrete classes that implement the operations. These classes will implement the two interface methods and the AbstractFactory interface. In our example, two concrete classes, RegularVehicleFactory and SportsVehicleFactory, will be created.ConcreteFactory.

RegularVehicleFactory.cs

The RegularVehicleFactory concrete class will produce Regular Vehicle Concrete Products. The Regular Car and Regular Bike are the Regular Vehicle Concrete Products in our scenario. To begin, create a class file called RegularVehicleFactory.cs, then paste and copy the code below. Observe that while a concrete product (new RegularBike and new RegularCar) is instantiated inside the procedure, the signatures of the Concrete Factory's methods return an abstract product (IBike) and (ICar). Thus, the Regular Family includes the following Concrete Factory, which Produces Regular Bike and Regular Car Products.

SportsVehicleFactory (ConcreteFactory2)

The SportsVehicleFactory concrete class will produce Sports Vehicle Concrete Products. The SportsBike and SportsCar are the Sports Vehicle Concrete Products in our example. To begin, create a class file called SportsVehicleFactory.cs, then insert the code below. It is evident that the Concrete Factory's signature methods return abstract products (IBike and ICar), but the method itself instantiates a concrete product (new SportsBike and new SportsCar). Thus, products related to the same sports family are produced by the following concrete factory: sports bikes and sports cars.

NOTE: In our example, the client can create families of linked or dependent objects using the interface provided by IVehicleFactory. Here are the RegularVehicleFactory and SportsVehicleFactory classes, which are two specific implementations of that interface. Bikes and cars are two distinct kinds of related item families that are produced by these two classes. The RegularVehicleFactory family includes the RegularCar and RegularBike classes. Conversely, the SportsVehicleFactory family includes the SportsCar and SportsBike classes.

Step 5: Client

The Client class uses the AbstractFactory and AbstractProduct interfaces to build a family of related objects. It will be the Programme class's Main method in our example. Thus, make the following changes to the Programme class's Main function.

Output:

Abstract Factory Design Pattern in C#

Abstract Factory Design Pattern UML (Class) Diagram:

Abstract Factory Design Pattern in C#

Let's examine each element that makes up the Abstract Factory Design Pattern:

  • Abstract Products: These will be the user interfaces used to create abstract products. In this case, we must specify the Operations that a Product ought to have. It is the interfaces for IBike.cs and ICar.cs in our example.
  • Concrete Products: The classes that implement the Abstract Product interface are referred to as Concrete Products. The Concrete Products in our example are the RegularBike, SportsBike, RegularCar, and SportsCar classes.
  • Abstract Factory: This will be an interface for processes that generate Abstract Product objects. In our example, it will be IVehicleFactory.
  • Concrete Factory: These classes provide implementations for the interface methods as well as the AbstractFactory interface. The concrete factory classes in our example are RegularVehicleFactory and SportsVehicleFactory.

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

Let's take a look at one Real-Time Example to demonstrate the step-by-step implementation of the Abstract Factory Design Pattern in C#. In order to display the course details, we wish to create a single application. The two course kinds that we wish to display here are front-end courses and back-end courses. Once more, we need to demonstrate the sources-the means by which students will acquire these courses-to them. The source, in this instance, may be offline or online. Now let's go on and explore how we can use the Abstract Factory Design Pattern in C# to construct this application.

Step 1: Creating Abstract Products

In order to create Abstract Products, we must declare interfaces at this location. Since we will be creating two types of recognizable products, like courses and sources, we need to develop two interfaces, or abstract classes, for each abstract product type. I'm going to make two interfaces here.

ICourse.cs

The following code should be copied and pasted into an interface called ICourse.cs. One of the Abstract Products will be this. The Course product family should have a base interface for each unique product. In this instance, this ICourse interface needs to be implemented by all Front-End and Back-End Course product variations. The interface that we have designed has three abstract methods, as you can see, and the FrontEndCourse and BackEndCourse subclasses will implement them.

ISource.cs

Copy and paste the following code into an interface called ISource.cs. We plan to release this as our second abstract product. Every individual product within the ISource product line ought to have a foundational interface. In this instance, the ISource interface needs to be implemented by both the online and offline versions of the Source products. As you can see, we used just one abstract method to generate the following interface. The Online and Offline subclasses of the ISource interface will carry out that procedure.

Step 2: Creating Concrete Products

The concrete product object, or the real product object that the associated concrete factory will produce, needs to be defined at this point. It is important to keep in mind that these concrete product classes need to implement both the interface methods and the abstract product interface. The concrete product class in our example needs to implement either the ICourse or ISource interface. Thus, let us develop four concrete products-FrontEndCourse, BackEndCourse, Online, and Offline-in accordance with our specifications.

FrontEndCourse.cs

In a class file called FrontEndCourse.cs, paste the following code into it. The Course product family includes the FrontEndCourse product shown below. It includes implementations for all three of the ICourse interface methods in addition to implementing the ICourse interface, as you can see.

Step 3: Creating Abstract Factory

The interface for the actions that will produce Abstract Product objects must now be developed. In our case, it will be ISourceCourseFactory. Copy and paste the following into a class file called ISourceCourseFactory.cs. As you can see, the two methods in this class are GetSource and GetCourse. The GetSource method creates different variations of Sources, whereas the GetCourse method creates different variations of courses.

We are merely stating that the methods and return type of these methods will be abstract products, such as ISource and ICourse, in this declaration. As a result, we can generate various objects (i.e., objects of ISource and ICourse subclasses) from the child classes.

Step 4: Creating Concrete Factories

To build actual product objects, we need to design concrete factory classes that implement abstract factory interfaces. Our example will create two concrete classes, OnlineSourceCourseFactory and OfflineSourceCourseFactory.

OnlineSourceCourseFactory .cs

The OnlineSourceCourseFactory concrete class will produce products for Online Source and Course Concrete. The Online Source and Course Concrete Products in our example are BackEndCourse and Online. To begin, create a class file called OnlineSourceCourseFactory.cs, then insert the code below. As you can see, a concrete product (new Online and new BackEndCourse) is instantiated inside the procedure, while the signatures of the Concrete Factory's methods return an abstract product (ICourse) and (ISource). Thus, the OnlineSourceCourse Family includes the following Concrete Factory Produces Online Source and BackEndCourse Products.

OfflineSourceCourseFactory.cs

Concrete Products for Offline Sources and Courses can be created using the OfflineSourceCourseFactory concrete class. The Offline Source and Course Concrete Products in our example are FrontEndCourse and Offline. Copy and paste the following code into the OfflineSourceCourseFactory.cs class file. As you can see, a concrete product (new Offline and new FrintEndCourse) is instantiated inside the procedure. At the same time, the signatures of the Concrete Factory's methods return an abstract product (ICourse) and (ISource). Thus, the OfflineSourceCourse Family includes the following Concrete Factory Produces Offline Source and FrontEndCourse Products.

NOTE: In our example, the client can create families of related or dependent objects using the interface provided by ISourceCourseFactory. Here, we have the OnlineSourceCourseFactory and OfflineSourceCourseFactory classes, which are two specific implementations of that interface. These two classes, Courses and Sources, produce two distinct kinds of connected object families. The OnlineSourceCourse class family includes the Online and BackEndCourse classes. However, the OfflineSourceCourse family includes the Offline and FrondEndCourse classes.

Step 5: Client

The Client class uses the AbstractFactory and AbstractProduct interfaces to build a family of related objects. In our example, it will be the Programme class's Main method. Thus, make the following changes to the Programme class's Main function.

Output:

Abstract Factory Design Pattern in C#

When to use Abstract Factory Design Pattern?

The following situations call for the use of the Abstract Factory Design Pattern in applications:

  • Form Families of Related items: You must implement this limitation when you have a group of related items that are intended to be used in tandem.
  • Maintain Uniformity in Products: Only items from the same family should be used in your application to guarantee consistency and compatibility.
  • Decouple Concrete Implementations: The pattern facilitates the separation of the client code from the interfaces' concrete implementations, which it depends on.
  • Promote Product Family Exchanges: Your application must be adaptable enough to function with several related product families and quickly switch between them.
  • Provide a Layer of Abstraction: When producing complex items requires a high degree of abstraction. This is particularly helpful for systems whose creation calls for configuration or dependency injection.
  • Support Scalability and configurability: Scalability and configurability are necessary for your application to enable the introduction of new product families without changing the client code already in place.
  • Platform-Specific Implementations: When your program must work with multiple environments or platforms, each of which has a particular set of products that must be implemented.
  • Mocking and Testing Made Easier: Abstract Factory can generate mock objects for unit testing, which simplifies the process of testing individual components.

Differences Between Abstract Factory and Factory Method Design Pattern:

Although both are creational design patterns, they are applied in various contexts and have unique qualities. It is essential to comprehend their distinctions in order to select the appropriate pattern for a given design issue.

Abstract Factory Design Pattern

  • Intent: Provides users the option to create families of dependent or linked items without having to declare their specific classes through an interface.
  • Abstractness: Deals with a collection of related goods (families) intended for shared usage.
  • Implementation: Consists of several manufacturing techniques, each of which usually yields a distinct kind of product. Typically, the Abstract Factory defines several ways to produce various types of items.
  • Use Case: This is employed when the system must function regardless of the manufacturing process of the goods it interacts with.
  • Flexibility: Greater flexibility because it can simultaneously produce several related object types.
  • Complexity: This method is more complex than the factory method because it has an extra abstraction layer for families of items.

Factory Method Design Pattern

  • Intent: This class provides an object creation interface but allows subclasses to select which class to instantiate. A class can delegate subclass instantiation to them using the Factory Method.
  • Abstractness: Focuses on a single product, yet it may come in multiple varieties. The creation of objects of a single type is the focus of the Factory Method pattern.
  • Implementation: This method uses a single manufacturing process to produce a single kind of good. Subclasses override the method to alter the kind of product produced.
  • Use Case: This is used when a class wants the objects it creates to be specified by its subclasses. It is also frequently used when a class is unable to predict the class of objects it must create.
  • Flexibility: Because it works with particular items, it is less flexible and more clear than Abstract Factory.
  • Complexity: Because there is only one product to focus on, it is easier to implement and comprehend.

Key Differences Between Abstract Factory and Factory Method

  • Scope of Creation: The factory Method creates a single product, whereas the Abstract Factory manages the creation of several connected or dependent goods.
  • Level of Abstraction: Because Abstract Factory deals with product families, it employs a higher level of abstraction.
  • Control Over Creation: In the Abstract Factory, creation is accomplished through object composition, whereas in the Factory Method, it is accomplished through inheritance (subclassing).
  • Use Cases: Use the factory method when working with single items; otherwise, use the Abstract Factory when you have a large number of objects that can be grouped.

Conclusion:

In conclusion, the C# Abstract Factory Design Pattern offers a means of encapsulating the construction of linked object families without requiring the specification of their concrete classes. Defining interfaces for both factories and products encourages loose coupling between client code and the actual implementations, which improves flexibility and maintainability.

Overall, the Abstract Factory Design Pattern is a useful tool for maintaining modular, extensible, and easily maintainable code when developing systems that necessitate the formation of families of related objects.






Latest Courses