Here, we will see how to create Chain of Responsibility Design Pattern with example.
The Chain of Responsibility design pattern is a behavioral pattern that allows an object to pass a request along a chain of potential handlers until one of them handles the request. This decouples the sender of the request from the receiver, promoting flexibility in assigning responsibility.
In a Chain of Responsibility pattern for a banking system where a customer requests loan approval, the request is passed through various authority levels: Loan Officer, Branch Manager, and Regional Manager. Each handler processes the loan if it's within their authority, or escalates it to the next level. We will explain in detail lator part of the article with code example.
To illustrate the Chain of Responsibility design pattern with a customer support system example, I'll create a simple C# program where different levels of support staff (e.g., Level 1, Level 2, and Manager) handle customer complaints based on the severity of the issue. If a support staff cannot handle the complaint, they pass it to the next handler in the chain. We will explain in detail lator part of the article with code example.
if-else
or switch
statements.Consider a customer support system where different levels of staff handle customer complaints based on the severity of the issue.
To illustrate the Chain of Responsibility design pattern with a customer support system example, I'll create a simple C# program where different levels of support staff (e.g., Level 1, Level 2, and Manager) handle customer complaints based on the severity of the issue. If a support staff cannot handle the complaint, they pass it to the next handler in the chain.
using System;
// Step 1: Define an interface for handling complaints
public interface IComplaintHandler
{
void SetNextHandler(IComplaintHandler nextHandler);
void HandleComplaint(int severity, string complaint);
}
// Step 2: Concrete Handlers implementing the interface
public class Level1Support : IComplaintHandler
{
private IComplaintHandler _nextHandler;
public void SetNextHandler(IComplaintHandler nextHandler)
{
_nextHandler = nextHandler;
}
public void HandleComplaint(int severity, string complaint)
{
if (severity == 1)
{
Console.WriteLine($"Level 1 Support handled the complaint: {complaint}");
}
else if (_nextHandler != null)
{
Console.WriteLine("Level 1 Support couldn't handle the complaint, escalating...");
_nextHandler.HandleComplaint(severity, complaint);
}
}
}
public class Level2Support : IComplaintHandler
{
private IComplaintHandler _nextHandler;
public void SetNextHandler(IComplaintHandler nextHandler)
{
_nextHandler = nextHandler;
}
public void HandleComplaint(int severity, string complaint)
{
if (severity == 2)
{
Console.WriteLine($"Level 2 Support handled the complaint: {complaint}");
}
else if (_nextHandler != null)
{
Console.WriteLine("Level 2 Support couldn't handle the complaint, escalating...");
_nextHandler.HandleComplaint(severity, complaint);
}
}
}
public class ManagerSupport : IComplaintHandler
{
public void SetNextHandler(IComplaintHandler nextHandler)
{
// This is the last in the chain, no next handler
}
public void HandleComplaint(int severity, string complaint)
{
if (severity >= 3)
{
Console.WriteLine($"Manager handled the complaint: {complaint}");
}
else
{
Console.WriteLine("Manager couldn't handle the complaint.");
}
}
}
// Step 3: Client code
public class Client
{
public static void Main(string[] args)
{
// Create handlers
IComplaintHandler level1 = new Level1Support();
IComplaintHandler level2 = new Level2Support();
IComplaintHandler manager = new ManagerSupport();
// Set up the chain of responsibility
level1.SetNextHandler(level2);
level2.SetNextHandler(manager);
// Complaints with varying severity
Console.WriteLine("Complaint with severity 1:");
level1.HandleComplaint(1, "Cannot log in to the system.");
Console.WriteLine("\nComplaint with severity 2:");
level1.HandleComplaint(2, "System performance is slow.");
Console.WriteLine("\nComplaint with severity 3:");
level1.HandleComplaint(3, "System is down and losing data.");
}
}
Handler Interface (IComplaintHandler)
Concrete Handlers
Client
Output
In a banking system, a customer might request loan approval. The request would be passed through different levels:
Each handler in the chain processes the request if it falls within their authority, or passes it on if it's beyond their capacity.
In a Chain of Responsibility pattern for a banking system where a customer requests loan approval, the request is passed through various authority levels: Loan Officer, Branch Manager, and Regional Manager. Each handler processes the loan if it's within their authority, or escalates it to the next level.
Defines the interface for handling loan requests.
Each handler (LoanOfficer, BranchManager, RegionalManager) implements the ILoanApprover interface and processes the loan based on its amount.
The client sends a loan request to the first handler in the chain.
using System;
// Step 1: Define an interface for loan approval
public interface ILoanApprover
{
void SetNextApprover(ILoanApprover nextApprover);
void ApproveLoan(int amount);
}
// Step 2: Concrete Handlers implementing the interface
public class LoanOfficer : ILoanApprover
{
private ILoanApprover _nextApprover;
public void SetNextApprover(ILoanApprover nextApprover)
{
_nextApprover = nextApprover;
}
public void ApproveLoan(int amount)
{
if (amount <= 50000)
{
Console.WriteLine($"Loan Officer approved the loan of {amount} dollars.");
}
else if (_nextApprover != null)
{
Console.WriteLine("Loan Officer cannot approve this loan, escalating to Branch Manager...");
_nextApprover.ApproveLoan(amount);
}
}
}
public class BranchManager : ILoanApprover
{
private ILoanApprover _nextApprover;
public void SetNextApprover(ILoanApprover nextApprover)
{
_nextApprover = nextApprover;
}
public void ApproveLoan(int amount)
{
if (amount <= 100000)
{
Console.WriteLine($"Branch Manager approved the loan of {amount} dollars.");
}
else if (_nextApprover != null)
{
Console.WriteLine("Branch Manager cannot approve this loan, escalating to Regional Manager...");
_nextApprover.ApproveLoan(amount);
}
}
}
public class RegionalManager : ILoanApprover
{
public void SetNextApprover(ILoanApprover nextApprover)
{
// No next approver, this is the last in the chain
}
public void ApproveLoan(int amount)
{
if (amount > 100000)
{
Console.WriteLine($"Regional Manager approved the loan of {amount} dollars.");
}
else
{
Console.WriteLine("Regional Manager couldn't approve the loan.");
}
}
}
// Step 3: Client code
public class Client
{
public static void Main(string[] args)
{
// Create handlers
ILoanApprover loanOfficer = new LoanOfficer();
ILoanApprover branchManager = new BranchManager();
ILoanApprover regionalManager = new RegionalManager();
// Set up the chain of responsibility
loanOfficer.SetNextApprover(branchManager);
branchManager.SetNextApprover(regionalManager);
// Loan requests of different amounts
Console.WriteLine("Loan request of 30,000 dollars:");
loanOfficer.ApproveLoan(30000); // Handled by Loan Officer
Console.WriteLine("\nLoan request of 75,000 dollars:");
loanOfficer.ApproveLoan(75000); // Handled by Branch Manager
Console.WriteLine("\nLoan request of 150,000 dollars:");
loanOfficer.ApproveLoan(150000); // Handled by Regional Manager
}
}
Handler Interface (ILoanApprover)
Concrete Handlers
Client
Output