Factory Method design pattern
The Factory Method design pattern is a flexible and powerful way to encapsulate object creation logic and to allow for the extensibility and substitution of concrete classes.
The Factory Method pattern is beneficial when a class cannot anticipate the type of objects it needs to create, or when it wants to delegate object creation responsibility to its subclasses. In this way, the Factory Method pattern enables loose coupling between the client and the objects it creates.
When using the Factory Method pattern, it is important to keep in mind that the factory method should only be responsible for creating objects and should not perform any other logic (Single Responsibility Principle).
Sample
The abstract creator
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The abstract class PaymentMethodCreator
public abstract class PaymentMethodCreator
{
//The factory method FactoryMethod is declared as abstract, so must be implemented by concrete subclasses.
public abstract IPaymentMethod FactoryMethod();
}The payment method interface
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The IPaymentMethod interface
public interface IPaymentMethod
{
//The ProcessPayment method is used to process a payment and returns a string indicating the result.
string ProcessPayment();
}Concrete implementation of payment with credit card concrete creator
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The CreditCardPaymentCreator class is a concrete implementation of the PaymentMethodCreator abstract class.
public class CreditCardPaymentCreator:PaymentMethodCreator
{
//The FactoryMethod implementation returns a new instance of the CreditCardPayment class.
public override IPaymentMethod FactoryMethod()
{
return new CreditCardPayment();
}
}Concrete implementation of credit card payment method
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The CreditCardPayment class is a concrete implementation of the IPaymentMethod interface.
public class CreditCardPayment:IPaymentMethod
{
//The ProcessPayment method returns a string indicating that the payment was processed using Credit Card.
public string ProcessPayment()
{
return "Credit Card";
}
}Concrete implementation of payment with PayPal concrete creator
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The PayPalPaymentCreator class is a concrete implementation of the PaymentMethodCreator abstract class.
public class PayPalPaymentCreator:PaymentMethodCreator
{
//The FactoryMethod implementation returns a new instance of the PayPalPayment class.
public override IPaymentMethod FactoryMethod()
{
return new PayPalPayment();
}
}Concrete implementation of the PayPal payment method
namespace FactoryMethodPattern.PaymentFactoryMethod;
//The PayPalPayment class is a concrete implementation of the IPaymentMethod interface.
public class PayPalPayment:IPaymentMethod
{
//The ProcessPayment method returns a string indicating that the payment was processed using PayPal.
public string ProcessPayment()
{
return "PayPal";
}
}Demonstration inside a controller :
Get Mohammed Ben Said’s stories in your inbox
Join Medium for free to get updates from this writer.
(don’t take the demonstration example as a good practice )
[HttpGet]
public IActionResult Get(PaymentMode paymentMode)
{
PaymentMethodCreator paymentMethodCreator;
switch (paymentMode)
{
case PaymentMode.PayPal:
paymentMethodCreator = new PayPalPaymentCreator();
break;
default:
paymentMethodCreator = new CreditCardPaymentCreator();
break;
}
var result = ProcessPayment(paymentMethodCreator.FactoryMethod());
return Ok(result);
}
private string ProcessPayment(IPaymentMethod paymentMethod)
{
return paymentMethod.ProcessPayment();
}Payment mode enum
namespace FactoryMethodPattern.PaymentFactoryMethod;
public enum PaymentMode
{
CreditCard,
PayPal
}Use cases
The Factory Method pattern can be used in the following cases:
- Abstraction of the object creation logic so that client classes are not aware of the details of object creation.
- The ability to change the concrete object class to be created without affecting client classes.
- The ability to define custom object creation logic based on specific application needs.
Conclusion
The Factory Method design pattern separates object creation logic and allows for the replacement and extension of concrete classes.
It is useful when a class is unable to predict the type of objects it needs to create or wants to delegate creation responsibility to its subclasses.






