다음을 통해 공유


Chain of Responsibility Pattern

Chain of Responsibility pattern is for a situation when there is a need to handle a single request by multiple handler objects. This ensures that the request need to be handled by one of the handlers in the Chain. 

In this pattern, the request is sent to the first handler, if the request can be processed by that, it will return the response, or it will be passed to its successor for processing, until it gets to the appropriate handler who could process the request. 

To demonstrate the fact let us take an example from the above class diagram.

public interface IHandler
    {
        IHandler Successor { get; set; }
        void ProcessRequest(IRequest request);
    }
 
public class FirstRequestHandler : IHandler
    {
 
        public IHandler Successor
        {
            get;
            set;
        }
 
        public void ProcessRequest(IRequest request)
        {
            Console.WriteLine("Request Received by FirstRequesthandler for processing", request);
 
            if (request.Seed <= 1)
            {
                // Process request
            }
            else
            {
                this.Successor.ProcessRequest(request);
            }
 
        }
    }
 
 public class SecondRequestHandler : IHandler
    {
        public IHandler Successor
        {
            get;
            set;
        }
 
        public void ProcessRequest(IRequest request)
        {
            Console.WriteLine("Request Received by SecondRequestHandler for processing", request);
 
            if (request.Seed < 5)
            {
                // Process request
            }
            else
            {
                this.Successor.ProcessRequest(request);
            }
 
        }
    }

Here the IHandler is a generic handler which handles some request. While calling the FirstRequestHandler, it delegates the Request to its successor which could be either SecondRequestHandler or anything else depending on what value is passed to it, such that it forms a Chain of responsibility ensuring the request is finally being processed by any of the handler. In this case, there should exist another handler which could handle seed >=5, but for simplicity sake we omitted the code. 

We also have a Request, which implements IRequest and have two members, one to hold Seed and another to call ProcessRequest. 

public interface IRequest
 {
     string Name { get; set; }
     int Seed { get; set; }
 }
 
 public class Request : IRequest
 {
 
     public string Name
     {
         get;
         set;
     }
 
     public int Seed
     {
         get;
         set;
     }
 
     public override string ToString()
     {
         return string.Format("Name : {0}, Seed : {1}", this.Name, this.Seed);
     }
 }

The client code should look like this :

static void Main(string[] args)
       {
 
           Request myRequest = new Request { Name = "Abhishek", Seed = 3 };
 
           IHandler secondRequest = new SecondRequestHandler();
           IHandler firstRequest = new FirstRequestHandler { Successor = secondRequest };
 
           firstRequest.ProcessRequest(myRequest);
       }

The Chain of Responsibility pattern is often required when one object cannot handle the entire process so that the token can be passed to a chain of objects holding specific responsibility.