Chain of Responsibility - Behavioural
Overview:
The Chain of Responsibility Pattern in C# is your code's relay race—passing the baton seamlessly for dynamic actions. Let's dive into this energetic coding relay:
Implementation in C#:
In C#, the Chain of Responsibility Pattern involves creating a chain of handlers to process requests, where each handler decides whether to handle the request or pass it to the next in line. Consider a scenario where discount requests in an e-commerce system are handled by a chain of discount handlers:
// Handler interface
public abstract class DiscountHandler
{
protected DiscountHandler successor;
public void SetSuccessor(DiscountHandler successor)
{
this.successor = successor;
}
public abstract void ProcessDiscountRequest(int amount);
}
// Concrete handler
public class SeniorDiscountHandler : DiscountHandler
{
public override void ProcessDiscountRequest(int amount)
{
if (amount > 100)
{
Console.WriteLine($"Senior discount applied for amount: {amount}");
}
else
{
successor?.ProcessDiscountRequest(amount);
}
}
}
// Concrete handler
public class VIPDiscountHandler : DiscountHandler
{
public override void ProcessDiscountRequest(int amount)
{
if (amount > 50)
{
Console.WriteLine($"VIP discount applied for amount: {amount}");
}
else
{
successor?.ProcessDiscountRequest(amount);
}
}
}
Pros:
-
Flexible Request Handling: Enables dynamic and flexible processing of requests.
-
Decouples Senders and Receivers: Removes the sender's knowledge of who will handle the request, promoting loose coupling.
-
Open/Closed Principle: Allows extending the chain without modifying existing code.
Cons:
-
Unprocessed Requests: There's no guarantee that a request will be processed, especially if the end of the chain is reached.
-
Performance Impact: Long chains may introduce performance overhead.
When to Use and When Not:
-
Use: When you want to decouple request senders from receivers and allow dynamic handling of requests.
-
Avoid: In scenarios where all requests must be guaranteed to be processed or when the chain becomes too long, impacting performance.
Usage in .NET Core Framework:
The Chain of Responsibility Pattern isn't explicitly used in the .NET Core framework, but its principles resonate in various aspects. Middleware in the ASP.NET Core pipeline and event handling in the framework exhibit chain-like behavior, where each component can process or pass the request to the next.
Real-Life Example:
Imagine an approval workflow in a company where different managers handle expense approval requests based on the amount. The Chain of Responsibility Pattern can model this dynamic process:
// Handlers for expense approval
var seniorManager = new SeniorManager();
var financeManager = new FinanceManager();
// Chain the handlers
seniorManager.SetSuccessor(financeManager);
// Process expense requests
seniorManager.ProcessExpenseRequest(1200);
Here, the seniorManager decides whether to approve the request or pass it to the financeManager for further processing.
In conclusion, the Chain of Responsibility Pattern in C# turns your code into a dynamic relay race—seamlessly passing the baton for flexible actions. While promoting flexibility and decoupling, developers should be mindful of unprocessed requests and potential performance impacts. Its influence in middleware and event handling within the .NET Core framework showcases its adaptability, allowing developers to design dynamic and extensible software relays that handle requests with the precision of a well-coordinated relay team.
No files yet, migration hasn't completed yet!