DEV Community

Cover image for Top 6 Design Patterns
Daniel Azevedo
Daniel Azevedo

Posted on

1 1

Top 6 Design Patterns

Hi devs,

Design patterns can help structure and optimize code, especially in complex systems like HR software, which often deals with managing employee records, processing payroll, and tracking performance. Here’s a look at some popular design patterns in C#, focusing on their uses in HR applications.


1. Singleton Pattern

  • Use Case: Centralized Configuration and Database Connection
  • Purpose: Ensures a class has only one instance and provides a global point of access to it.
  • Example: HR systems often need to maintain a single, consistent connection to a central database. A Singleton pattern could ensure only one instance of the database connection is used, minimizing memory usage and enhancing performance.
   public class DatabaseConnection
   {
       private static DatabaseConnection _instance;
       private static readonly object _lock = new object();

       private DatabaseConnection() { }

       public static DatabaseConnection Instance
       {
           get
           {
               lock (_lock)
               {
                   if (_instance == null)
                   {
                       _instance = new DatabaseConnection();
                   }
                   return _instance;
               }
           }
       }
   }
Enter fullscreen mode Exit fullscreen mode

2. Factory Pattern

  • Use Case: Generating Employee Profiles Based on Role
  • Purpose: Creates objects without specifying the exact class of object that will be created.
  • Example: Different employee roles may require different types of onboarding processes. A Factory pattern can dynamically create the appropriate onboarding objects for different roles, whether full-time, part-time, or contractor.
   public interface IEmployee
   {
       void DisplayDetails();
   }

   public class FullTimeEmployee : IEmployee
   {
       public void DisplayDetails() => Console.WriteLine("Full-Time Employee Profile");
   }

   public class Contractor : IEmployee
   {
       public void DisplayDetails() => Console.WriteLine("Contractor Profile");
   }

   public class EmployeeFactory
   {
       public static IEmployee CreateEmployee(string type)
       {
           return type switch
           {
               "FullTime" => new FullTimeEmployee(),
               "Contractor" => new Contractor(),
               _ => throw new ArgumentException("Invalid Employee Type")
           };
       }
   }
Enter fullscreen mode Exit fullscreen mode

3. Observer Pattern

  • Use Case: Notifying Stakeholders of HR Changes
  • Purpose: Allows one object (subject) to notify other objects (observers) about changes without directly referencing them.
  • Example: An HR application can notify relevant departments (Payroll, Benefits) when an employee's status changes (e.g., promotion or termination).
   public class Employee
   {
       private readonly List<IObserver> _observers = new List<IObserver>();
       public string Status { get; private set; }

       public void UpdateStatus(string status)
       {
           Status = status;
           NotifyObservers();
       }

       public void Attach(IObserver observer) => _observers.Add(observer);
       private void NotifyObservers()
       {
           foreach (var observer in _observers)
               observer.Update(Status);
       }
   }

   public interface IObserver
   {
       void Update(string status);
   }

   public class PayrollDepartment : IObserver
   {
       public void Update(string status) => Console.WriteLine($"Payroll updated: {status}");
   }
Enter fullscreen mode Exit fullscreen mode

4. Facade Pattern

  • Use Case: Simplifying Onboarding Process
  • Purpose: Provides a simplified interface to a complex subsystem.
  • Example: The onboarding process in HR might involve multiple steps, like setting up payroll, benefits, and IT access. A Facade pattern can bundle these steps into a single onboarding interface, making it easier for the HR team.
   public class OnboardingFacade
   {
       private readonly PayrollService _payroll = new PayrollService();
       private readonly BenefitsService _benefits = new BenefitsService();
       private readonly ITAccessService _itAccess = new ITAccessService();

       public void OnboardNewEmployee(string employeeId)
       {
           _payroll.Setup(employeeId);
           _benefits.Setup(employeeId);
           _itAccess.GrantAccess(employeeId);
       }
   }
Enter fullscreen mode Exit fullscreen mode

5. Strategy Pattern

  • Use Case: Calculating Payroll Based on Employee Type
  • Purpose: Defines a family of algorithms, encapsulates each one, and makes them interchangeable.
  • Example: Different payroll calculations may be needed for salaried employees, hourly employees, and contractors. The Strategy pattern allows HR to dynamically apply the right calculation method.
   public interface IPayrollStrategy
   {
       decimal Calculate(decimal basePay);
   }

   public class SalariedPayroll : IPayrollStrategy
   {
       public decimal Calculate(decimal basePay) => basePay;
   }

   public class HourlyPayroll : IPayrollStrategy
   {
       public decimal Calculate(decimal hours) => hours * 20;
   }

   public class PayrollContext
   {
       private readonly IPayrollStrategy _strategy;

       public PayrollContext(IPayrollStrategy strategy) => _strategy = strategy;

       public decimal ExecuteCalculation(decimal basePay) => _strategy.Calculate(basePay);
   }
Enter fullscreen mode Exit fullscreen mode

Why Design Patterns Matter in HR Systems

By implementing these patterns in HR applications, developers can improve code structure, facilitate easier maintenance, and create more scalable systems. As HR systems grow, they become increasingly complex, so patterns like these help keep systems manageable.

Keep coding

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read full post →

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up