Take advantage of the chain of responsibility design pattern to draw on a chain of objects to handle requests Credit: 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. Open Visual Studio IDE Click File -> New -> Project In the New Project dialog window, select the “Class Library (.Net Framework)” project template 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. Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos