How to use the chain of responsibility design pattern in C#

Take advantage of the chain of responsibility design pattern to draw on a chain of objects to handle requests

How to use the chain of responsibility design pattern in C#
Thinkstock

Design patterns are solutions to common problems and complexities in software design. As we have discussed here before, they are classified into three distinct categories: creational, structural, and behavioral. The chain of responsibility design pattern falls under the behavioral category and can be used to reduce coupling between the sender of a request and the receiver object that handles the request.

The Gang of Four definition of the chain of responsibility design pattern:

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.

Essentially, in the chain of responsibility design pattern you have a list or a chain of objects that may handle a request. Each object can either handle the request or forward the request to another handler. In this article we’ll discuss the purpose of the chain of responsibility design pattern and how it can be implemented in C#.

The chain of responsibility design pattern

The participants in a typical implementation of the chain of responsibility pattern include an abstract handler, a concrete handler, and the client or the consumer. The abstract handler is the interface that is responsible for defining the contract. The concrete handler is the component that implements the operations defined in the abstract handler; the concrete handler either handles the request itself or forwards the request to a successor. Lastly, the client component is responsible for initiating the request.

Let’s now explore how we can implement this design pattern in C#. Assuming that you have Visual Studio installed in your system, you can follow these steps to create a console application project in the Visual Studio IDE.

  1. Open Visual Studio IDE
  2. Click File -> New -> Project
  3. In the New Project dialog window, select the “Class Library (.Net Framework)” project template
  4. Specify the name and location for your project and click OK to save

The console application project created will include a default file named Class1.cs. You can rename this file as you like or create a new file. Let’s now dive into the code.

Create the abstract handler

Consider the following abstract base class.

public abstract class HandlerBase
    {
        protected HandlerBase successor;
        public void SetSuccessor(HandlerBase handlerBase)
        {
            successor = handlerBase;
        }
        public abstract void ProcessRequest(string request);
    }

The HandlerBase class contains two methods – the SetSuccessor and the ProcessRequest methods. While the former is used to set a successor object to handle the request, the latter is the method that will be processing the request. We will implement these methods in the concrete classes shown next.

Create the concrete handlers 

Consider the following two concrete classes.

public class ConcreteHandlerA : HandlerBase
   {
       public override void ProcessRequest(string request)
          {
              //Some code
          }
   }
public class ConcreteHandlerB : HandlerBase
   {
       public override void ProcessRequest(string request)
          {
              //Some code
          }
   }

Implement the chain of responsibilities

Lastly, we must set up the chain of responsibilities. The following piece of code illustrates how this can be achieved.

static void Main(string[] args)
        {
            string[] codes = { “A001”, “A002”, “A003” };
            HandlerBase handlerA = new ConcreteHandlerA();
            HandlerBase handlerB = new ConcreteHandlerB();
            handlerA.SetSuccessor(handlerB);
            handlerB.SetSuccessor(handlerA);
            foreach (var s in codes)
            {
                handlerA.ProcessRequest(s);
            }
            Console.Read();
        }

Refer to the code listing shown above. Note how instances of the concrete handlers have been created and the responsibilities delegated. (I will leave it to you to implement the ProcessRequest method appropriate to your needs.) Also note how the string values have been passed as a parameter to the ProcessRequest method.

This was just a structural implementation of the design pattern. Feel free to change this implementation as appropriate to meet your needs. By taking advantage of the chain of responsibility design pattern, you can facilitate reusability and loose coupling in your application.

Copyright © 2018 IDG Communications, Inc.