HTML clipboardDefinition
GoF -> A way of passing a request between a chain of objects
-
The Chain of Responsibility pattern works with a list of Handler objects that
have limitations on the nature of the requests they can deal with. If a handler
object cannot handle a request, it passes it on to the next handler object in
the chain. At the end of the chain, there can be either default or exceptional
behavior.
- The pattern chains the receiving objects together, and then passes any
request messages from object to object until it reaches an object capable of
handling the message.
- Chain of Responsibility simplifies object interconnections. Instead of
senders and receivers maintaining references to all candidate receivers, each
sender keeps a single reference to the head of the chain, and each receiver
keeps a single reference to its immediate successor in the chain.
- Sometimes, the request object has to go through the chain objects mandatorily,
like Http pipeline.
- Sometimes only through few handlers.
Design
Let us take an example; we are conducting a GK context. We have three teams to
answer the questions. Each team will have 10000 ms to answer the questions, and
team one has to start the each question. If team one didn't answer the question,
it will be passed on to the next team.
Avoid coupling the sender of a request to its receiver by giving more than one
object a chance to handle the request. Chain the receiving objects and pass the
request along the chain until an object handles it.
UML Diagram
From GoF
Code
---------------- handler Base class ----------------------
public
abstract class
Handlerbase
{
public
Handlerbase NextTeam { get;
private set; }
public
ContextObject Question { get;
private set; }
public Handlerbase(Handlerbase
nextHandler, ContextObject question)
{
NextTeam = nextHandler;
Question = question;
}
public abstract
void HandleRequest();
}
---------------- queue
object one ----------------------
public
class TeamOne:
Handlerbase
{
public TeamOne(Handlerbase
nextHandler, ContextObject question) :
base(nextHandler, question) { }
public override
void HandleRequest()
{
Console.WriteLine("Question
: {0}", Question.Question.ToString());
Console.WriteLine("*******************************************"));
Console.WriteLine("Wating
for team one to respond");
Thread.Sleep(10000);
Console.WriteLine("\t
no response from team one.....");
NextTeam.HandleRequest();
}
}
---------------- chain
object two ----------------------
public class
TeamTwo :
Handlerbase
{
public TeamTwo(Handlerbase
nextHandler, ContextObject question) :
base(nextHandler, question) { }
public override
void HandleRequest()
{
Console.WriteLine("Wating
for team two to respond");
Thread.Sleep(10000);
Console.WriteLine("\t
no response from team two.....");
NextTeam.HandleRequest();
}
}
---------------- chain
object tree ----------------------
public class
TeamThree :
Handlerbase
{
public TeamThree(Handlerbase
nextHandler, ContextObject question) :
base(nextHandler, question) { }
public override
void HandleRequest()
{
Console.WriteLine("Wating
for team three to respond");
Thread.Sleep(10000);
Console.WriteLine("\t
no response from team three as well .....");
}
}
----------------
Request----------------------
public class
ContextObject
{
public string
Question { get; set;
}
}
---------------- Client----------------------
static void
Main(string[] args)
{
ContextObject question =
new ContextObject()
{ Question = "Who is an ediat in your team?"
};
TeamThree teamThree =
new TeamThree(null,
question);
TeamTwo teamTwo =
new TeamTwo(teamThree,
question);
TeamOne teamOne =
new TeamOne(teamTwo,
question);
teamOne.HandleRequest();
Console.ReadKey();
}