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
ISalaryinterface. - 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 specificISalaryimplementation.
4. JuniorEmployee and SeniorEmployee (Classes)
- Purpose: Concrete implementations of the abstract class
Employee. - Method:
GetSalary(): Implements the abstractGetSalary()method from the baseEmployeeclass, returning an instance ofJuniorSalaryorSeniorSalary, 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 (
JuniorSalaryandSeniorSalary) define the products that the Factory Method will create. -
Employee acts as the abstract Creator class. It defines an interface to create an object (
ISalaryin this case) but leaves the implementation of how that object is created to the derived classes (JuniorEmployeeandSeniorEmployee). -
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(JuniorSalaryorSeniorSalary).
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}");
}
}

