paint-brush
Understanding Chain of Responsibility Pattern in C#by@ssukhpinder

Understanding Chain of Responsibility Pattern in C#

by Sukhpinder SinghJune 22nd, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

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 obj

Coin Mentioned

Mention Thumbnail
featured image - Understanding Chain of Responsibility Pattern in C#
Sukhpinder Singh HackerNoon profile picture

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#

C# has been around for quite some period, and it continues to develop, obtaining more enhanced features.

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.

=> Sample Code

Thank you for reading, and I hope you liked the article.

Read behind a paywall at https://medium.com/c-sharp-progarmming/how-to-use-chain-of-responsibility-pattern-f0f4896efc74