Factory pattern
The objective of this post is to explain and show how to implement the Factory Pattern in a basic way.
Pre-requisites
Check all the description and information related to the Factory Pattern and return here to see a practical example.
Description
Suppose a company has different levels of employees: Junior, Mid-Level and Senior. Each level has a different base salary. We want to implement a system that calculates the salary of an employee according to his seniority.
This idea can be visualized in the following diagram:
Components of the Diagram
1. ISalary (Interface)
- Purpose: Defines the common interface for salary objects.
- Method:
CalculateSalary()
: A method that must be implemented by classes that implement this interface to calculate the salary.
2. JuniorSalary and SeniorSalary (Classes)
- Purpose: Concrete implementations of the
ISalary
interface. - Method:
CalculateSalary()
: Implements the specific logic to calculate the base salary for a Junior and a Senior, respectively.
3. Employee (Abstract Class)
- Purpose: Defines an abstract class representing an employee.
- Method:
GetSalary()
: An abstract method that returns an object of typeISalary
. This method will be implemented by derived classes to provide a specificISalary
implementation.
4. JuniorEmployee and SeniorEmployee (Classes)
- Purpose: Concrete implementations of the abstract class
Employee
. - Method:
GetSalary()
: Implements the abstractGetSalary()
method from the baseEmployee
class, returning an instance ofJuniorSalary
orSeniorSalary
, respectively.
Objective in the Factory Method Pattern
The Factory Method pattern is used to encapsulate object creation logic. It allows a class to delegate the responsibility of object instantiation to its subclasses.
-
ISalary and its implementations (
JuniorSalary
andSeniorSalary
) define the products that the Factory Method will create. -
Employee acts as the abstract Creator class. It defines an interface to create an object (
ISalary
in this case) but leaves the implementation of how that object is created to the derived classes (JuniorEmployee
andSeniorEmployee
). -
JuniorEmployee and SeniorEmployee act as the ConcreteCreator classes. They implement the abstract
GetSalary()
method, which uses the Factory Method to create and return a concrete instance ofISalary
(JuniorSalary
orSeniorSalary
).
By using the Factory Method pattern in this example, we achieve more modular and extensible code. If in the future we need to add a new salary type or employee type, we simply create new implementations of ISalary
and Employee
without modifying the existing code.
Implementation
using System;
public interface ISalary
{
decimal CalculateSalary();
}
public class JuniorSalary : ISalary
{
public decimal CalculateSalary()
{
return 30000;
}
}
public class SeniorSalary : ISalary
{
public decimal CalculateSalary()
{
return 80000;
}
}
public abstract class Employee
{
public abstract ISalary GetSalary();
}
public class JuniorEmployee : Employee
{
public override ISalary GetSalary()
{
return new JuniorSalary();
}
}
public class SeniorEmployee : Employee
{
public override ISalary GetSalary()
{
return new SeniorSalary();
}
}
class Program
{
static void Main(string[] args)
{
// Create instances of JuniorEmployee and SeniorEmployee
Employee juniorEmployee = new JuniorEmployee();
Employee seniorEmployee = new SeniorEmployee();
// Get salaries for Junior and Senior Employees
ISalary juniorSalary = juniorEmployee.GetSalary();
ISalary seniorSalary = seniorEmployee.GetSalary();
// Print salaries
Console.WriteLine($"The salary for a Junior Employee is: {juniorSalary.CalculateSalary():C}");
Console.WriteLine($"The salary for a Senior Employee is: {seniorSalary.CalculateSalary():C}");
}
}