Understanding Chain of Responsibility Pattern in C#

Written by ssukhpinder | Published Invalid Date
Tech Story Tags: csharp | design-patterns | chain-responsibility-pattern | aspnetcore | programming | good-coding-practices | dotnet | coding | web-monetization

TLDRvia the TL;DR App

According to Gang of Four, it defines a chain of responsibilities to process a request. In other words, pass the request from one object to another until an object accepts its responsibility.

Use Case

Let’s consider an example of a claims system in any corporate company. Here is the list of the price range that can be approved and by whom.
100–1000 Rs => Junior/Senior Engineers => Approved by Manager
1001–10000 Rs => Managers => Approved by Senior Manager
If the amount is outside the 10000 range, it requires exceptional approval from the senior manager.
Implement the above use case using the Chain of Responsibility design pattern. So, the claim class has the following properties.
public class Claim{
  public int Id{get;set;}
  public double amount{get;set;}
}

Prerequisites

Basic knowledge of OOPS concepts.Any programming language knowledge.
The article demonstrates the usage of Chain of Responsibility design patterns using the C# programming language. So, to begin with, C#

Getting Started

Firstly, let's define what functions a claim approver can perform and set a hierarchy for employees at different levels. Implement an abstract class as shown below
public abstract class ClaimApprover
{
    protected ClaimApprover claimApprover;
    public void SetHierarchy(ClaimApprover claimApprover)
    {
        this.claimApprover = claimApprover;
    }
    public abstract void ApproveRequest(Claim claim);
}
As per the use case, let’s drive class “junior/senior” claim requestor. Notice that this class/designation of employees cannot approve any claims.
public class Junior : ClaimApprover
{
    public override void ApproveRequest(Claim claim)
    {
        System.Console.WriteLine("Cannot approve");
    }
}
Similarly, let’s define implement for Manager and Senior Manager roles.
public class Manager : ClaimApprover
{
    public override void ApproveRequest(Claim claim)
    {
        if (claim.amount >= 100 && claim.amount <= 1000)
        {
            System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Manager");
        }
        else if (claimApprover != null)
        {
            claimApprover.ApproveRequest(claim);
        }
    }
}
Notice that based upon amount range, if within the range, the claim should be approved by the Manager; otherwise, the request will carry forward onto the Senior Manager.
public class SeniorManager : ClaimApprover
{
    public override void ApproveRequest(Claim claim)
    {
        if (claim.amount > 1000 && claim.amount <= 10000)
        {
            System.Console.WriteLine($"Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager");
        }
        else
        {
            System.Console.WriteLine($"Exceptional approval for Claim reference {claim.Id} with amount {claim.amount} is approved by Senior Manager");
        }
    }
}
Similarly, if the amount range is within the Senior Manager range, the claim can be approved by the Manager; otherwise, being last in the hierarchy, an exceptional approval is done for an amount outside the range.

How to use the Chain of Responsibility pattern?

ClaimApprover junior = new Manager();
ClaimApprover sukhpinder = new Manager();
ClaimApprover singh = new SeniorManager();
junior.SetHierarchy(sukhpinder);
sukhpinder.SetHierarchy(singh);

Claim c1 = new Claim() { amount = 999, Id = 1001 };
Claim c2 = new Claim() { amount = 10001, Id = 1002 };

junior.ApproveRequest(c1);
sukhpinder.ApproveRequest(c2);
  1. Define claim approver: junior, although it cannot approve any claims.
  2. Define claim approver: manager “sukhpinder.”
  3. Define claim approver: senior manager “singh.”
  4. Setup hierarchy relationship for junior, i.e., claims approver is the manager.
  5. Setup hierarchy relationship for the manager, i.e., claims approver is the senior manager.
  6. Create two different ranges of claims.
  7. Junior sends the claim request to the manager.
  8. The manager sends the claim request to the senior manager.

Output

  • Claim reference 1001 with amount 999 is approved by Manager
  • Exceptional approval for Claim reference 1002 with amount 10001 is approved by Senior Manager
For line 1 output, the amount was within the range, so the manager approved it.
For line 2 output, although the senior manager approves it, the amount was outside the range.

Github Repo

The following repository shows the above use case implementation using a Chain of Responsibility Design Pattern in the console-based application.
Thank you for reading, and I hope you liked the article.

Written by ssukhpinder | I'm Sukhpinder Singh, a passionate self-taught .Net developer from India.
Published by HackerNoon on Invalid Date