Objective ๐ฏ
Allow a single request to be processed by multiple handlers in the chain. Each handler will decide either to process the request or to pass it to the next handler in the chain.
Type โ
โ๏ธBehavioral: Describes how objects interact/communicate between themselves.
โCreational: Describes how to instantiate an object without large and complex.
โStructural: Describes how objects/classes are composed to form larger structures.
UML ๐
Participants ๐
โข Handler:
- Defines an interface for handling the requests
โข Concrete Handler:
- Implements Handler interface
- Handles the request, either processing it or passing it to the successor handler
โข Client:
- Initiates the flow by forwarding the request to a Concrete Handler object
Sample Code ๐ฎ
Structural Example ๐๏ธ
public static class ChainOfResponsibilityStructural
{
public static void Execute()
{
Handler lConcreteHandler1 = new ConcreteHandler1();
Handler lConcreteHandler2 = new ConcreteHandler2();
Handler lConcreteHandler3 = new ConcreteHandler3();
lConcreteHandler1.SetSuccessor(lConcreteHandler2);
lConcreteHandler2.SetSuccessor(lConcreteHandler3);
lConcreteHandler1.HandleRequest("AAA");
lConcreteHandler1.HandleRequest("BBB");
}
}
public abstract class Handler
{
protected Handler _SuccessorHandler;
public void SetSuccessor(Handler prSuccessorHandler)
{
_SuccessorHandler = prSuccessorHandler;
}
public abstract void HandleRequest(string prRequest);
}
public class ConcreteHandler1 : Handler
{
public override void HandleRequest(string prRequest)
{
Console.WriteLine("ConcreteHandler1 - Handling Request: " + prRequest);
if (_SuccessorHandler != null)
_SuccessorHandler.HandleRequest(prRequest);
}
}
public class ConcreteHandler2 : Handler
{
public override void HandleRequest(string prRequest)
{
Console.WriteLine("ConcreteHandler2 - Handling Request: " + prRequest);
if (_SuccessorHandler != null)
_SuccessorHandler.HandleRequest(prRequest);
}
}
public class ConcreteHandler3 : Handler
{
public override void HandleRequest(string prRequest)
{
Console.WriteLine("ConcreteHandler3 - Handling Request: " + prRequest);
if (_SuccessorHandler != null)
_SuccessorHandler.HandleRequest(prRequest);
}
}
Output
Real-world Example ๐ฅ
public static class ChainOfResponsibilityPractical
{
public static void Execute()
{
Approver lAssistantManager = new AssistantManager();
Approver lManager = new Manager();
Approver lDirector = new Director();
lAssistantManager.SetSuccessor(lManager);
lManager.SetSuccessor(lDirector);
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Requesting approval for a order of cost USD 50.");
lAssistantManager.ApproveOrder(50);
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Requesting approval for a order of cost USD 250.");
lAssistantManager.ApproveOrder(250);
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Requesting approval for a order of cost USD 500.");
lAssistantManager.ApproveOrder(500);
Console.WriteLine("---------------------------------------------------------------");
Console.WriteLine("Requesting approval for a order of cost USD 600.");
lAssistantManager.ApproveOrder(600);
}
}
public abstract class Approver
{
protected Approver _SuccessorApprover;
public void SetSuccessor(Approver prApprover)
{
_SuccessorApprover = prApprover;
}
public abstract void ApproveOrder(int prCost);
}
public class AssistantManager : Approver
{
public override void ApproveOrder(int prCost)
{
if (prCost <= 50)
Console.WriteLine("Assistant Manager - Order Approved. Cost: USD" + prCost);
else
{
Console.WriteLine("Assistant Manager - Can't approve (cost > 50), sending to next approver in the hierarchy.");
if (_SuccessorApprover != null)
_SuccessorApprover.ApproveOrder(prCost);
}
}
}
public class Manager : Approver
{
public override void ApproveOrder(int prCost)
{
if (prCost <= 250)
Console.WriteLine("Manager - Order Approved. Cost: USD" + prCost);
else
{
Console.WriteLine("Manager - Can't approve (cost > 250), sending to next approver in the hierarchy.");
if (_SuccessorApprover != null)
_SuccessorApprover.ApproveOrder(prCost);
}
}
}
public class Director : Approver
{
public override void ApproveOrder(int prCost)
{
if (prCost <= 500)
Console.WriteLine("Director - Order Approved. Cost: USD" + prCost);
else
Console.WriteLine("Director - Not approved, cost is too high");
}
}
Output
Source Code ๐ฒ
ย