Understanding and Implementing Factory Pattern in C#

In this article we will try to understand what is Factory Pattern, what are the benefits of this pattern and how can we implement this pattern using C#.

Background

It is almost impossible to have an application that contains only one class. Typically an application will have many classes involved, each with a dedicated responsibility, to implement the desired functionality. Which would mean that it is inevitable for the classes to communicate with other classes. This can easily be achieved if we let the classes instantiate the classes it needs and the call the methods on these classes.

So if we have a class Athat want to call a method of class B, we can simply have an object of Binside Aand call its methods whenever we need to. The code will look something like following.

This approach of having the class instances contained inside other classes will work but it has some downsides. The first problem is that each class needs to know about every other class that it wants to use. This will make this application a maintenence nightmare. Also, the above approach will increase the coupling between the classes.

From the best practices’ perspective whenever we are designing our classes we should keep the dependency inversion principle in mind when it comes to dependency between classes. Dependency Inversion Principle says that the higher level modules should always depend on abstractions rather than lower level modules directly. So we should always design our classes in such a way that they always depend on the interfaces or abstract classes rather than other concrete classes.

So the classes we saw in the above example will change. We first need to have an interface that Acan use to call DoTaskOne. Class Bshould implement this interface. The new classes will look like following.

The above code shows the classes perfectly designed where the higher lever modules depend on abstractions and the lower level modules implementing these abstractions. But wait… How are we going to create and object of B. Should we still do that as we did in the previous code i.e. doing a new on Bin the A'sconstructor? But would it not defeat the whole purpose of having loose coupling?

This is exactly where the Factory pattern will be useful. The Factory completely hides the process of creating objects. Factory pattern totally abstract our the responsibility of creating classes from the client classes. The major benefit of this is that our client code is completely ignorant of creation process of dependent classes. So to instantiate the actual in our above code we have to do something like the following in the constructor.

This loose coupling also good from the extensibility perspective. With the factory pattern in place, the client code also has the possibility of using multiple dependent classes as long as these dependent classes adhere to the contract i.e. implement interface. So in the above example the client code will simply not be calling the factory method but will also be providing some information that can be used to identify the concrete object that needs to be created.

Using the Code

The example we saw above was rather contrived. To understand the Factory pattern, let us try to implement a sample application. Lets say we have an eCommerce application and we have 2 payment gateways integrated with our application. Let call these payment gateways as BankOne and BankTwo. The BankOne charges 2% on credit cards if the order is less that 50 USD and 1% if it is more than 50 USD. BankTwo one other hand charges flat 1.5% for all the amounts.

So our payment module presents the user with three options as:

  • BankOne
  • BankTwo
  • Best for me

Lets start by looking at our Productmodel. This product model will represent the product that the user is trying to purchase.

Now let us look at IPaymentGatewayinterface first. This interface will define the contract that all the payment gateways i.e. banks’ classes should conform to.

Note: In real world the MakePayment will also accept user information to identify the user. We are not showing it here to keep the sample free from digression.

Now lets create the classes that will contain the actual code for making the payment by invoking the bank specific API.

Now its time to create our factory class to handle all the gory details of creating these objects. To be able to identify what payment mechanism user has selected, lets define a simple Enum PaymentMethod.

The factory class will use this enum to identify what payment gateway concrete class should be created. Lets look at our factory class implementation now.

What our factory class is doing is that it is accepting the user selected payment gateway and then based on the selection it is creating the concrete payment gateway class. As we can see that it has a lot of logic to decide which payment gateway to select, we have effectively abstracted out all these gory details from the client code. Otherwise every class that want to use a payment gateway would have to write all this logic. Lets now look at how the client class can use this factory method to make the payment.

Now our client class does not depend on the concrete payment gateway classes. It also does not have to worry about the creation logic of the concrete payment gateway classes. All this is nicely abstracted out in the factory class itself.

The Factory pattern is a very useful pattern when it comes to keeping our client code decoupled from dependent classes. It enables the application to be maintained more easily. It also makes it very easy to extend as new concrete classes can be added as without impacting the existing concrete classes and the client code.

Looking at GoF Factory Method

GoF defines factory method as “Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiate to subclasses”. If we look at the class diagram for Factory Method (Reference: GoF Design Patterns):

factoryGof

Lets see what each of these classes represents:

  • Product: defines the interface of objects the factory method creates ( IPaymentGateway)
  • ConcreteProduct: implements the Product interface ( BankOne, BankTwo)
  • Creator: declares the factory method, which returns an object of type Product. ( PaymentGatewayFactory)
  • ConcreteCreator: overrides the factory method to return an instance of a ConcreteProduct

Now if we compare our current implementation with the GoF factory method, we have our interface IPaymentGatewaywhich is interface of objects the factory method creates. We have our BankOneand BankTwoclasses that are the ConcreteProducts. As for the factory classes, we are using a single factory class PaymentGatewayFactoryinstead of having a hierarchy. But on a closer look we will see that our factory class is in fact the Creatorclass of GoF patterns. The only difference is that instead of being a pure abstract class our class comes with some abstract behavior.

So how can we plug in and use ConcreteCreatorwith our design. Lets say we want to create more concrete payment gateway classes that will be used by other parts of the application. To do this, we first have to have new enums values for the new concrete classes like following:

Now we can have one factory class derived from our PaymentGatewayFactory class which will contain the logic for these new payment gateways.

Now wherever we want to use the newly added payment mechanism, we just have to create PaymentGatewayFactory2instead of PaymentGatewayFactoryand all the 5 payment gateway concrete classes will be available to the client code.

Now our Creator is not a pure abstract class but it comes with some default functionality which can be overridden by the the concrete factories derived from it.

Point of interest

In this article, we looked at simple factory pattern and the scenarios where factory pattern can be useful. We have implemented a class factory pattern using C#. The article has been written from the beginner’s perspective. I hope this has been informative.

History

  • 09 Feb 2015: First version

Download article code from here: FactoryTest

One thought on “Understanding and Implementing Factory Pattern in C#