Back to: Design Patterns in C# With Real-Time Examples
Factory Method Design Pattern in C#
In this article, I will discuss the Factory Method Design Pattern in C# with Examples. Please read our previous article discussing the Factory Design Pattern in C# with one Real-Time Example. The Factory Method Design Pattern belongs to the Creational Design Pattern Category and is one of Real-Time Applications’ most frequently used design patterns.
Note: The most important point is that the Factory Method Design Pattern is not the exact same as the simple Factory Design Pattern we discussed in our previous article. Most people think both are the same; thus, they use the terms Factory and Factory Method interchangeably, which is not right.
What is the Factory Method Design Pattern?
According to the Gang of Four, the Factory Method Design Pattern Defines an interface for creating an object but lets the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses.
The Factory Method Design Pattern provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. In the factory method design pattern, we will create an abstract class as the Factory class, which will create and return the product instance, but it will let the subclasses decide which class to instantiate.
Example to Understand Factory Method Design Pattern in C#:
Let us understand the Factory Method Design Pattern with one real-time example using C#. We are going to develop an application to show credit card information. This is the same example we discussed in our previous article, but instead of the Factory Design Pattern, we will use the Factory Method Design Pattern.
As you can see in the diagram below, we have three credit cards, i.e., MoneyBack, Titanium, and Platinum. These credit cards are nothing but our Product classes. Again, these three Credit Card classes are the subclasses of the CreditCard super interface (which we can also call Abstract Product). The CreditCard super interface defines the operations (i.e., GetCardType, GetCreditLimit, and GetAnnualCharge) that need to be implemented by the subclasses (i.e., MoneyBack, Titanium, and Platinum), i.e., the Product classes.
As per the definition of the Factory Method Design Pattern, we need to create an abstract class or interface for creating the object. Please have a look at the following diagram. This will be our Abstract Creator Class that declares the Factory Method, i.e., CreateProduct(), which will return an object of type Product via the abstract product type, i.e., CreditCard. The CreditCardFactory Creator class declares the factory method, i.e., MakeProduct(), that will return an object of a Product class. The CreditCardFactory subclasses usually provide the implementation of the MakeProduct method.
As you can see, the above abstract class (i.e., CreditCardFactory) contains two methods: one abstract method, i.e., MakeProduct(), which is going to be our Factory method, and one concrete method, i.e., CreateProduct(). The CreateProduct() method internally calls the MakeProduct() method of the subclass, which will create and return the product instance.
Please have a look at the following diagram. As we have three credit cards (i.e., MoneyBack, Platinum, and Titanium), we created three subclasses (i.e., PlatinumFactory, TitaniumFactory, and MoneyBackFactory) by implementing the Abstract CreditCradFactory class and providing implementation to the MakeProduct abstract method. This method will return the actual product object, i.e. (MoneyBack, Platinum, and Titanium) via the product interface type, i.e., CreditCard.
Let’s see how the client will consume the above CreditCardFactory to create an object. Please have a look at the following diagram. The client code works with an instance of a concrete creator, i.e., the classes that implement the CreditCardFactory abstract class. The CreateProduct method will return the actual product object via the abstract Product interface type, i.e., Creditcard.
The above image shows that the client wants to create a Platinum object. To do so, the clients call the CreateProduct method on the PlatinumFactory instance, which will return a concrete Platinum object via the CreditCard type. Similarly, suppose the client wants to create a Titanium object. In that case, the client needs to call the CreateProduct method on the Titanium Factory instance, which will return a concrete Titanium object.
Implementing the Factory Method Design Pattern in C#:
The Factory Method design pattern involves a structure where a Creator class delegates the responsibility of instantiating its objects to its subclasses. The Factory Method Design Pattern consists of the following components:
- Product: This is the interface or abstract class defining the product the factory method will create.
- ConcreteProduct: These are the specific implementations of the Product interface or abstract class.
- Creator: This abstract class or interface declares the FactoryMethod().
- ConcreteCreator: Subclasses of Creator that implement the FactoryMethod() to produce ConcreteProduct instances.
Now, let’s proceed to implement the example step by step using the Factory Method Design Pattern in C#.
Step 1: Creating Product Interface (CreditCard)
Create a class file named CreditCard.cs and copy and paste the following code. This will be our Product interface, which will provide the signature of the common functionalities that the concrete product classes should implement.
namespace FactoryMethodDesignPattern { // The CreditCard interface declares the operations that all // concrete products must implement. public interface CreditCard { string GetCardType(); int GetCreditLimit(); int GetAnnualCharge(); } }
Step 2: Creating Concrete Products (MoneyBack, Titanium, and Platinum)
This is a class implementing the Product interface (CreditCard) and providing implementation to the interface methods. As we have three types of Credit cards in our example, we will create three classes (MoneyBack, Titanium, and Platinum) by implementing the CreditCard interface.
MoneyBack.cs
Create a class file named MoneyBack.cs, then copy and paste the following code.
namespace FactoryMethodDesignPattern { // MoneyBack Product provides implementations of the CreditCard interface methods. public class MoneyBack : CreditCard { public string GetCardType() { return "MoneyBack"; } public int GetCreditLimit() { return 15000; } public int GetAnnualCharge() { return 500; } } }
Titanium.cs:
Create a class file named Titanium.cs and copy and paste the following code.
namespace FactoryMethodDesignPattern { //Titanium Product provides implementations of the CreditCard interface methods. public class Titanium : CreditCard { public string GetCardType() { return "Titanium Edge"; } public int GetCreditLimit() { return 25000; } public int GetAnnualCharge() { return 1500; } } }
Platinum.cs:
Create a class file named Platinum.cs, then copy and paste the following code.
namespace FactoryMethodDesignPattern { //Platinum Product provides implementations of the CreditCard interface methods. public class Platinum : CreditCard { public string GetCardType() { return "Platinum Plus"; } public int GetCreditLimit() { return 35000; } public int GetAnnualCharge() { return 2000; } } }
Step 3: Creating Abstract Creator (CreditCardFactory)
The Abstract Creator declares the factory method, which returns an object of type Product. As per the definition, we must create an abstract class or interface to create the object. So, let us create an abstract class that will be our factory class with a publicly exposed method. That method is the factory method, which will return the instance of the product. So, create a class file named CreditCardFactory.cs and copy and paste the following code.
namespace FactoryMethodDesignPattern { // The CreditCardFactory Creator class declares the factory method // that is going to return an object of a Product class. // The CreditCardFactory subclasses usually provide the implementation of the MakeProduct method. public abstract class CreditCardFactory { protected abstract CreditCard MakeProduct(); // Also note that The Creator's primary responsibility is not creating products. // Usually, it contains some core business logic that relies on Product objects, returned by the factory method. public CreditCard CreateProduct() { //Call the MakeProduct which will create and return the appropriate object CreditCard creditCard = this.MakeProduct(); //Return the Object to the Client return creditCard; } } }
We created the above abstract class with one abstract method, MakeProduct(), and one concrete method, CreateProduct(). The CreateProduct() method internally calls the MakeProduct() method of the subclass, which will create and return the product instance. The MakeProduct() will be implemented by the concrete creator classes, i.e., the sub-classes of the abstract creator class, CreditCardFactory.
Step 4: Creating Concrete Creator (PlatinumFactory, MoneyBackFactory, and TitaniumFactory)
The Concrete Creator class implements the Abstract Creator class and overrides the factory method. The overridden Factory Method will return an instance of a Concrete Product via the base Product interface. As we have three types of Credit Cards, we will create three Concrete Creator classes, namely PlatinumFactory, MoneyBackFactory, and TitaniumFactory, which will implement the abstract Creator Class, namely the CreditCardFactory class.
PlatinumFactory Concrete Creator
So, create a class file named PlatinumFactory.cs and copy and paste the following code.
namespace FactoryMethodDesignPattern { // PlatinumFactory Concrete Creators override the factory MakeProduct method // to create and return the Platinum Product public class PlatinumFactory : CreditCardFactory { // The signature of the method uses the abstract product CreditCard type, // Even though the concrete Platinum product is returned from the method. // This way the Abstract Creator CreditCardFactory can stay independent of concrete product classes. protected override CreditCard MakeProduct() { CreditCard product = new Platinum(); return product; } } }
MoneyBackFactory Concrete Creator
So, create a class file named MoneyBackFactory.cs and copy and paste the following code.
namespace FactoryMethodDesignPattern { // MoneyBackFactory Concrete Creators override the factory MakeProduct method // to create and return the MoneyBack Product public class MoneyBackFactory : CreditCardFactory { // The signature of the method still uses the abstract product CreditCard type // Even though the concrete MoneyBack product is actually returned from the method. // This way the Creator can stay independent of concrete product classes. protected override CreditCard MakeProduct() { CreditCard product = new MoneyBack(); return product; } } }
TitaniumFactory Concrete Creator
So, create a class file named TitaniumFactory.cs and copy and paste the following code.
namespace FactoryMethodDesignPattern { // TitaniumFactory Concrete Creators override the factory MakeProduct method // to create and return the Platinum Product public class TitaniumFactory : CreditCardFactory { // The signature of the method uses the abstract product CreditCard type, // Even though the concrete Titanium product is returned from the method. // This way the Abstract Creator CreditCardFactory can stay independent of concrete product classes. protected override CreditCard MakeProduct() { CreditCard product = new Titanium(); return product; } } }
As you can see, the above three classes implement the MakeProduct method of the CreditCardFactory class. That’s it. We are done with our implementation. Let’s compare the Gang of Four Definition with our example.
According to Gang of Four, we must define an interface or abstract class to create an object. In our example, it is an abstract class, i.e., the CreditCardFactory class. The second part of the definition says that let the subclasses decide which class to instantiate. In our example, the subclasses are PlatinumFactory, MoneyBackFactory, and TitaniumFactory. These subclasses will decide which class to instantiate, for example, MoneyBack, Titanium, and Platinum.
Step 5: Consuming the Factory Method in the Client Code:
The client code works with an instance of a concrete creator, i.e., we need to create an instance of either PlatinumFactory, MoneyBackFactory, or TitaniumFactory. Then, we need to call the CreateProduct method on the concrete creator instance, which will return the actual product instance via the product interface, i.e., CreditCard type.
If you want to create an instance of the Platinum CreditCard, call the CreateProduct method on the PlatinumFactory instance. Similarly, if you want the instance of Titanium CreditCard, call the CreateProduct method of the TitaniumFactory instance. So, modify the Main method of the Program class as follows.
using System; namespace FactoryMethodDesignPattern { class Program { static void Main(string[] args) { // The client code works with an instance of a concrete creator // The CreateProduct will return the actual product instance via the product interface //PlatinumFactory CreateProduct method will return an instance of Platinum Product via the CreditCard interface CreditCard creditCard = new PlatinumFactory().CreateProduct(); if (creditCard != null) { Console.WriteLine("Card Type : " + creditCard.GetCardType()); Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit()); Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge()); } else { Console.Write("Invalid Card Type"); } Console.WriteLine("--------------"); //MoneyBackFactory CreateProduct method will return an instance of Platinum Product via the CreditCard interface creditCard = new MoneyBackFactory().CreateProduct(); if (creditCard != null) { Console.WriteLine("Card Type : " + creditCard.GetCardType()); Console.WriteLine("Credit Limit : " + creditCard.GetCreditLimit()); Console.WriteLine("Annual Charge :" + creditCard.GetAnnualCharge()); } else { Console.Write("Invalid Card Type"); } Console.ReadLine(); } } }
When we run the application, it displays the output as expected, as shown in the below image.
Factory Method Design Pattern UML (Class) Diagram:
Once we understand how to implement the Factory Method Design Pattern in C#, let us try to understand the UML (Unified Modeling Language) or Class diagram of it. For a better understanding, please look at the following diagram, which shows the different components of the Factory Method Design Pattern. Here, I am comparing the Factory Method Design Pattern UML diagram with our CreditCard example so that you can easily understand the different components of the Factory Method Design Pattern.
Understanding Each Component
Let us understand each component of the Factory Method Design Pattern:
- Product: This is an interface for creating objects. Here, we need to define the Opeartions a Product should have. In our example, it is the CreditCard interface.
- Concrete Product: This is a class that implements the Product interface. In our example, the MoneyBack, Titanium, and Platinum classes are Concrete Products. These classes implement the Product interface, i.e., CreditCard.
- Abstract Creator: This is an abstract class and declares the factory method, which returns an object of type Product. In our example, the CreditCardFactory abstract class has the CreateProduct Factory method, which will create and return an instance of the actual product. Internally, this CreateProduct method will call the subclass MakeProduct method, creating and returning the appropriate product instance.
- Concrete Creator: These classes implement the Abstract Creator class and override the factory method to return an instance of a Concrete Product.
In the next article, I will discuss Real-Time Examples of the Factory Method Design Pattern in C#. In this article, I explain the Factory Method Design Pattern in C# step by step with an example. I hope this article will help you with your needs. I would like to have your feedback. Please post feedback, questions, or comments about this article.
Really, Very good example and explain in easy way.
Keep it up.
Thank you!
This website is so informative!!!
On your another article “Factory Design Pattern in C#”, you mentioned one of disadvantages of Simple Factory Design Pattern is the need to add new if-else should we need to add new product, which violates open-closed principle:
https://dotnettutorials.net/lesson/factory-design-pattern-csharp/
In the end of article above, you mentioned that Factory Method design pattern could overcome the above problem, but I still see if-else used in CreditCardFactory class of this example.
Would you please advise?
Thank you!
This is also what I thought.
I think it is a good point
Correct.
The if-else is just checking for null, which means if it’s not null.
The if else you see is from the Client, not bound to the Credit card or its children.
So, what is different from client code version that has not used pattern
How will this is better than
CreditCard creditcard = new MoneyBack();
I agree with DK, I dont see the point, How is adding all this complication better than just doing CreditCard creditcard = new MoneyBack(); ???
Correct
My best guess would be the following:
With the Factory Method, we can now take an input (eg from the user) which will give the client the type of factory to be used. This way we can controll where the changes are made in case it will be needed in the future. If we’re just doing:
CreditCard creditcard = new MoneyBack();
We’re basically enforcing the client to unneccesarily depend on something (in this case the MoneyBack class) which might change in the future and thereby require changes in the client. Think of using a class variable instead of encapsulating it in a property.
If this is actually the case, then the following statement is a bit misleading:
CreditCard creditCard = new PlatinumFactory().CreateProduct();
A better example would if so be:
CreditCardFactory UserSelectedFactory = ReadInputFromUser(); // Read in the desired factory
CreditCard creditCard = UserSelectedFactory.CreateProduct(); // Create the desired product
Now we have a structured place to add, create and change products, without touching the client. It allows us to follow the open/close principle for the abstract factory and product interface, and it creates a local place in the code for potential changes in the future.
Then again, I can’t say I know this for sure. In the book, there’s a lot more to this design pattern than covered by the post. There they eg put more emphasis that this design pattern is meant to put the “type” of objects to be created in the hands of the subclass-Factory (eg PlatinumFactory). Which is also defined by the authors: “… let the subclasses decide which class to instantiate …”, so the PlatinumFactory should decide the class to be created. The example in the post doesn’t make this obvious as it only shows each factory to handling a single class each.
Say the PlatinumFactory can also create different CreditCard classes (they have PlatinumPremium, PlatinumPlus, PlatinumBasic etc..), then it’s up to PlatinumFactory to define these classes, and also how these classes will be selected. Perhaps the factory method takes a parameter: CreateCreditCard(paymentPlan) which will decide what type of Platinum card should be instantiated. The abstract CreditCardfactory here is oblivious to the type being created, it just knows that an ICreditCard should be instantiated.
I don’t know if this rant made things clearer or not, but it gave me some clarity to write it out, so if you made it to the end and realized I don’t know what I’m talking about..
..I’m sorry to have wasted your time q(‘c’)p
It is written that “The Factory Method Design Pattern is used, when we need to create the object (i.e. instance of the Product class) without exposing the object creation logic to the client.”
Although there is no more logic to create new instances in this example, you can use this pattern when the creation required some info that you don’t want to expose.
The if else used on the client is nothing more than defensive programming.to avoid any exception that might be raised if for any reason the factory has failed to create the object.
Nice article. Keep up the code work.
Below are my thoughts over the “Factory Method”;
In a Typical scenario where the number of condition are going to be fixed.
For Example:
in case of Boolean outcome where the result will always either be true or false.
So in this case we can say it for sure that there will be only two conditions.
And we can safely use the “factory” pattern.
While in the another scenario where the multiple branching caused due to inconsistent “if else” can be avoided using “factory method” design pattern.
For example;
Types of Transport
It can be a Car,
It can be a Truck,
It can be an Airplane,
It can be a Train,
So, as we can see It can be anything. And thus our number of if else condition are unpredictable
So, instead of adding undue branching with if else we better use “State” Design Pattern
Or “Factory Method” Design Pattern considering the context of the situation.
The example of card type in above article might seems like a over engineering but considering the scenario where we don’t know how many such card type will keep on coming we prefer to add the pattern. So as to keep the system extensible.
However, care must be taken that we are not over complicating thing with design patterns .
There are always trade offs. And we should weigh situation(context of problem) before going further with implementing pattern
Hey, you can resolve this problem just by putting the below code where i have used reflection.
public interface ICreditCard
{
void Show();
}
public class PremiumCard : ICreditCard
{
private readonly double _cost;
public PremiumCard(double cost)
{
this._cost =cost;
}
public void Show()
{
Console.WriteLine(“Premium Card {0}”, this._cost);
}
}
public class SilverCard : ICreditCard
{
private readonly double _cost;
public SilverCard(double cost)
{
this._cost =cost;
}
public void Show()
{
Console.WriteLine(“Silver Card {0}”, this._cost);
}
}
public abstract class CreaditCardFactory
{
public abstract ICreditCard Create(double cost);
}
public class PremiumCardFactory : CreaditCardFactory
{
public override ICreditCard Create(double cost)
{
return new PremiumCard(cost);
}
}
public class SilverCardFactory : CreaditCardFactory
{
public override ICreditCard Create(double cost)
{
return new SilverCard(cost);
}
}
public enum CardCategories{
PremiumCard,
SilverCard
}
public class CreaditCard
{
private readonly CreaditCardFactory _factory;
public CreaditCard(CardCategories type)
{
this._factory = (CreaditCardFactory)Activator.CreateInstance(Type.GetType(Enum.GetName(typeof(CardCategories),type) + “Factory”));
}
public static CreaditCard Run(CardCategories type)
{
return new CreaditCard(type);
}
public ICreditCard Execute(double cost)
{
return _factory.Create(cost);
}
}
public class Program
{
public static void Main(string[] args)
{
var factory = CreaditCard.Run(CardCategories.PremiumCard).Execute(22.5);
factory.Show();
}
}
public abstract class CreditCard
{
public string CardType { get; set; }
public int CardLimit { get; set; }
public int AnnualCharge { get; set; }
}
public class Platinum : CreditCard
{
}
public class Titanium : CreditCard
{
}
public class MoneyBack : CreditCard
{
}
public static class CreditCardFactory
{
public static CreditCard CreditCard(string selection)
{
var cardType = Type.GetType(“OOD.dotnetFactorytut.” + selection);
var constructor = cardType.GetConstructor(new Type[] { });
var creditCard = (CreditCard)constructor.Invoke(new object[] { });
creditCard.CardType = Console.ReadLine();
creditCard.CardLimit = int.Parse(Console.ReadLine());
creditCard.AnnualCharge = int.Parse(Console.ReadLine());
return creditCard;
}
}
class Program
{
static void Main(string[] args)
{
bool exit = false;
while (!exit)
{
Console.WriteLine();
Console.WriteLine(“Platinum”);
Console.WriteLine(“Titanium”);
Console.WriteLine(“MoneyBack”);
Console.WriteLine(“Exit”);
Console.WriteLine();
Console.Write(“Select demo: “);
string choice = Console.ReadLine();
if (choice == “Exit”)
exit = true;
else
{
var credit = CreditCardFactory.CreditCard(choice);
Console.WriteLine($”CardType : {credit.CardType}\nCardLimit : {credit.CardLimit}\nAnnualCharge : {credit.AnnualCharge}”);
}
Console.WriteLine();
Console.WriteLine(“Press ‘Enter’ for menu”);
Console.ReadLine();
Console.Clear();
}
}
}
I don’t understand, why should be have “CreateProduct()” rather direct use of “MakeProduct()” ? Could you please help me out to understand this.
If you will use CreateProduct() only, you won’t be able to defer the object creation to subclasses.
I am bit confused; what is the benefits of using ‘PlatinumFactory’ in-place of ‘Platinum’ concert class? as client side we have to specify each interface instance to create object!!
in both case, any changes on concrete class there would be no change at client side code for object creation..
Please clear my doubt
I too have same question, based on user input again we need use if-else condition to call either platinum factory or titanium factory.
I think in the Simple Factory Method we had a different scenario which based on a string value that was card type, we were trying to choose which concrete class should be created. but if we want to apply the factory method to the same example, again we need if-else to choose which factory class we use to create the object and we just create more complexity. yes, the pattern is not violating solid principles inside factory class but I think it is only useful when we exactly know which type we need and not based on a condition. so I believe It just adds more complexity.
Can you explain why don’t make the MakeProduct() as public abstract, then just call this instead of call CreateProduct() indirectly?
Thanks,
Eric
MakeProduct() and CreateProduct() both does same thing. Since we are calling the MakeProduct() in CreateProduct().
and the Object creation logic is in the MakeProduct() and implementation of that is present in the ConcreteCreator.cs (i.e class which is used for the creation of the Object).
So, In the ConcreteCreator.cs Method we are overriding the MakeProduct() method because the method says that we are making here.
and in the client method, the article writer may have thought it is not readable to use the method MakeProduct() for user understanding. so, he used CreateProduct() which does the same.
that is just for better understanding for the developer. I believe!
There is no issue in calling the same method MakeProduct() everywhere. it is just to make sure user understandable
PlatinumFactory().CreateProduct()
This is code from main()
If new credit card added then we need to change client code?
Is it proper?
In my opinion factory design pattern is better where in case of new credit card added then change will be in credit card interface only
Can’t we make MakeProduct as public in CreditCardFactory? Why to use one method?
In this example also, we have to change the code in client side if one more Card type come into the picture….. Then what is the benefit of using this in place of factory pattern?
I still don’t understand what Factory Method does better than Simple Factory or even Non-Factory ???
An example of using this design template is in a table when you want to create a new row – the new row must be the same as the table associated with it – therefore we would like the person who creates it – to always be from a table
Also – this design template is suitable when we also want the created classes of credit cards to be divided according to different types for each subtype
Also – the advantage of the method that does not accept parameters to create – gives us more flexibility in that each type of card can decide for itself which type to produce by its unique characteristics
Another use of this template – when we want, for example, that every time an instance of a credit card is produced in the system – then another class in the program is updated or produced as well
Hi, I still do not see the advantage of factory method. I feel it shifts the problem of if-else statements to client side (from Factory class, of Factory Design Pattern). The client needs to know which factory it needs to make use of. E.g. Platinum Factory, Titanium Factory etc. And if there are a greater number of factories, again client will end up using switch or if-else statements at his end. Could you please help me in understanding this?
In Factory design pattern
There is one Factory where we make all product based on the client requirements and client calls only that Factory and we decide what product need to make based on input
But
In Factory Method design pattern
We make seperate Factory for each product and that Factory will return product
Now client have to decide which Factory need to call based on his requirements
You are talking about Abstract Factory Design Patterns. Factory Method and Abstract Factory Design Patterns are different.