Chain Of Responsibility Design Pattern

Learn how it simplifies request handling in object chains, improves code flexibility, and supports clean architecture in .NET applications.

Chain Of Responsibility Design Pattern

Introduction

As applications grow in complexity, clean separation of concerns becomes essential. Enter the Chain of Responsibility design pattern — a behavioral pattern that allows multiple objects to handle a request without tightly coupling the sender to the receiver.


🔄 What Is the Chain of Responsibility Pattern?

The Chain of Responsibility is a behavioral design pattern that passes a request along a chain of handlers. Each handler either processes the request or passes it to the next handler in the chain.

💡 Real-World Analogy:

Imagine a customer service system: if a support agent can’t handle your issue, they escalate it to a manager, then to a director — that’s a chain of responsibility.


🛠️ Implementation in C#: Method Chaining Approach

Let’s break down the code sample you provided using a simple fantasy-themed example.

var goblin = new Creature("Goblin", 1, 1);
var root = new CreatureModifier(goblin);
root.Add(new DoubleAttackModifier(goblin));
root.Add(new IncreaseDefenseModifier(goblin));
root.Handle();
WriteLine(goblin);

🧬 Core Components

Creature: Our base object with Attack and Defense values.

public class Creature
{
  public string Name;
  public int Attack, Defense;
}

CreatureModifier: The base handler in the chain.

public class CreatureModifier
{
  protected Creature creature;
  protected CreatureModifier next;

  public void Add(CreatureModifier cm) =>
      next = next == null ? cm : next.Add(cm);
}

Concrete Modifiers:

  • DoubleAttackModifier doubles the attack stat.
  • IncreaseDefenseModifier adds defense if attack is low.
  • NoBonusesModifier stops the chain.

This pattern gives developers granular control over the object’s transformation process, with each modifier representing a separate concern.


📌 Best Practices

  • Keep each handler focused on one responsibility.
  • Use interfaces or abstract base classes for handlers.
  • Avoid modifying shared state unpredictably — especially in multithreaded environments.

🏁 Conclusion

The Chain of Responsibility design pattern is a powerful tool for building scalable systems. By separating responsibilities into discrete, chainable components, you enhance flexibility, maintainability, and testability in your codebase.

Use this pattern when handling complex processing flows — such as validation pipelines, middleware chains, or command handlers — and enjoy a cleaner, more modular .NET application architecture.

Subscribe to arash.ninja

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe