How to use the Abstract Factory design pattern in C#

The Abstract Factory Pattern is one level of abstraction higher than Factory Method Design Pattern.

Using the Abstract Factory Pattern a framework is defined, which produces objects that follow a general pattern and at runtime this factory is paired with any concrete factory to produce objects that follow a defined pattern.

Code available on Github

The Abstract Factory Pattern is a creational Gang of Four (GoF) design pattern, defined in their seminal book Design Patterns: Elements of Reusable Object-Oriented Software, in which they presented a catalogue of simple and succinct solutions to commonly occurring design problems.

What is the Abstract Factory Pattern

The Abstract Factory Pattern is used when you want to return several related classes of objects, each of which can return several different objects on request. Typically you may use the Abstract Factory Pattern, in-conjunction with other factory patterns like Simple Factory Pattern and the Factory Method Pattern.

The best way to think of the Abstract factory pattern, is that it is a super factory, or a *factory of factories*. Typically it is an interface which is responsible for creating a factory of related objects without explicitly specifying the derived classes.

Abstract Factory Pattern

The key components of the Abstract Factory Pattern are :

  • Abstract Factory: An abstract container which creates abstract objects.
  • Concrete Factory: Implements an abstract container to create concrete object.
  • Abstract Object: An interface defined with the attributes of the Object to be created.
  • Concrete Object: The actual object by referring related abstract objects.
  • Client: The client application that creates families of related objects using the factory.

The factory pattern is a way of replacing manual object instantiation with delegation to a class whose purpose is to create objects


Example Abstract Factory in C#

In our example we will continue with our sample game application of building a Vehicle depending on a set of user requirements passed into our method. This is hypothetical game we started creating in the Factory Method Design Pattern article. We will refactor this application to introduce abstract factory design pattern and provide the user with some additional choices they can provide.

The user will be able to stipulate the Number of Wheels, whether they have an engine, if they will be carrying cargo and if they will be carrying passengers. Once this information is supplied the application will return the best type of vehicle to suit their purpose. The game will be a simple Console application which simply asks the users to enter their choice and responds with an answer.

I’ve kept the code rather simple, in order to illustrate a point. The code for our Entire console is follows:

The code in this section despite being quite messy at this point, and pretty hard to read, (This is rather deliberate at this stage because we will be addressing this in a future article!) – does nothing more than ask a user a set of questions and adds answers to a defined VehicleRequirements is then passed to method which then calls the Abstract Factory which I will explain shortly.

Featured Book Review


The GetVehicle Method will return an instance of class which implements our IVehicle intefacce.

This is the method where we actually start to see the implementation of our Abstract Factory – or our factory of factories.

In this contrived example, our method is going to do a check to see, if the type of vehicle we want to build has an engine or not and based on that data it will select whether we want to create a Motor powered vehicle or Pedal powered vehicle and redirect to appropriate factory to create the vehicle. Ideally, you’d probably defer this choice the Abstract factory itself, but I just wanted to illustrate the point, that using an abstract factory class we can still make decisions on which factory we wanted to use.

Both of the methods defined on the abstract class will provide us with an object implementing IVehicle interface. The application doesn’t control the ultimate end type of object but it can select which factory it wants to build the object based on certain criteria.

Our abstract factory is actually an abstract class which is defined with 2 methods which require the implementation of 2 additional factories. You’ll notice that these two methods are also just implementations of IVehicleFactory.

This class is nothing more than an abstract class and has no implementation code at all. We could if desired have some default implementation code which could be overidden if desired. However, for my purpose I have just left them as stubs.

The class enables the implementation of two different factories, each will be responsible for returning different vehicle types. In our Case Cycles or Motor Vehicles.

Our actual implementation of our class abstract factory class, would possibly look something like the following.

Our implementation of our Vehicle Factory class, in truth is probably considered bad coding practice, are nothing more than Pass Through Methods , but I have intentionally implemented this to illustrate a point that ultimately our methods will more than likely invoke an alternate factory.

A Pass Through Method is one that does little except invoke another method, whose signature is similar or identical to that of the calling method.
This typically denotes there is not a clean division between classes

If we take a look at an implementation of one of the factories i.e CycleFactory you’ll notice that I have actually elected to make use of the Factory Method Pattern to create an instance of an object to return. I chose this to labour another point, in that as a developer you can use these patterns interchangeably and coincide with other patterns.

This also serves as an emphasis on the notion of Factory of Factories concept.

I have tried to keep the logic in this sample as contrived as possible, but also try to illustrate that this factory is ultimately responsible for instantiating the object that is passed back to calling client. This serves to highlight that, the client does not need to concern itself with creating the object and that the decision point for which object to return is separated by several layers.

This enables improved testability via separation of concerns. Even in this simple example you would notice that client, only needs to concern itself with data that has been entered i.e. Validate the data as close the source as possible, it then passes that data to an abstract factory class which then disseminates it to the required factories to create an object.

It is this feature which makes the Abstract Factory method such a popular and powerful pattern to learn to provide greater opportunity to unit test code. Using the pattern in-conjunction with other patterns further enhance testability of your code.


Refactor the Factory

The code for our abstract factory is working, but lets be honest it is rather **Dirty Code** and it does not actually provide all the benefits we could get from using the abstract factory pattern. For a few reasons I alluded to earlier.

Let’s conduct a slight refactor of factory pattern. The first one, is we could probably do with either removing the option of the client app from having to make the decision of which factory to use, or we could extend on that option.

In order to illustrate an option, lets do a complete refactor and tidy up the code. My first option would be to remove those nasty **Pass Through Methods** they really do not provide a clean abstraction and in actually fact we could remove the the need to have 2 Factory methods on our class and just provide one. This will make our class even easier to understand and remove any chance of errors.

In our case lets just provide the client with one choice of Factory. Our new refactored abstract factory class will now only have one method.

With this complete, lets go ahead and complete the refactor of the implementation of our Factory Class.

You’ll notice here, we’ve actually used the constructor to pass in the requirements and use the data to determine which factory is best suited to create our vehicle of choice. This will minimize the risk of the client using the wrong factory.

The complexity of clients GetVehicle method has greatly been reduced, they now no longer need to concern themselves with inspecting the data and determining which factory to use. All they need to do is pass in the VehicleRequirements in the constructor and call the Create method and all the magic will just happen.

When developing a module, look for opportunities to take a little bit of extra suffering upon yourself in order to reduce the suffering of your users.


Consequences of Abstract Factory

The main purpose of the Abstract Factory Pattern is to isolate concrete classes created. The actual class names of the classes are hidden in the factory and need not to be known at the client level at all.

Due to the isolation of classes, developers can change or interchange these product class families as desired. Since only one instance type of concrete classes can be generated, this keeps developers cannot inadvertently create classes of different class families. However, the pattern does incur additional effort to add new class families since there is a need to define new, unambiguous conditions to create new classes.

Despite all the classes that Abstract Factory generates inheriting the same base class or interface, there is nothing to prevent developers adding additional methods or have differing implementation logic. This presents problems when using any sub-class because you cannot ensure if your sub-class has the same methods available.

To solve this problem, you can ensure that all classes only implement methods defined on a common interface or inherit the abstract class.

Featured Book Review


A Philosophy of Software Design

A Philosophy of Software Design

John Ousterhout

Price: £14.13

Conclusion

The Abstract Factory pattern enables developers to generically define families of related objects, leaving the actual concrete implementation of those objects to be implemented as needed.

The Abstract Factory pattern is pretty common in C#, and the .net Framework has libraries that use it to provide a way to extend and customize their standard components.

Gary Woodfine

Freelance Full Stack Developer at threenine.co.uk
Helps businesses by improving their technical proficiencies and eliminating waste from the software development pipelines.

A unique background as business owner, marketing, software development and business development ensures that he can offer the optimum business consultancy services across a wide spectrum of business challenges.

Affiliate Disclaimer

Disclosure: Please note that some of the links included in the blog posts are affiliate links, which means I will earn a commission if you decide to make a purchase.

I only include affiliate links to products, services and companies that I have personal experience and have actually used. I only recommend them because they are helpful and useful, not because of the small commissions I make if you decide to buy something.

Please do not spend any money on these products unless you feel they are relevant, suitable and will help you achieve your goals.

Buying anyone of these products and the commisions earned will not make me an overnite multi millionaire, but they will help to cover the hosting costs and compensate for the countless hours and effort I put in to create meaningful and valuable free content I provide to help others succeed.

You've also undoubtedly noticed that I also use various advertising networks - unless of of course you're using an Ad blocker, this is also an attempt to reduce my monthly deficit I experience in providing free relevant, valuable and on occassion insightful content for the benefit of others.

I only really make some money if people click on the ads, unless of course you consider 1c per 1000 impressions real money!

Bear in mind just how many impressions I need to make before I can cover my £20 hosting costs a month!

If you are using an adblocker and guilt stricken you can of course donate using any of the buttons below, but I won't be holding my breath.


Buy me a coffeeBuy me a coffee
π