The chain of responsibility pattern is used to process varied requests, each of which may be dealt with by a different handler.
Simply put, its a chain of hander objects to process a request or pass it to the next handler. This decouples requests from handlers.
Example Chain : Validate object in multiple steps
Often the simplest example using basic language features can explain a pattern, the following examples are based on Code Radiance
Create the Request object and the class you want to validate, here we will validate Person
1 2 3 4 5 6 7 8 9 10 11 12 13
publicclassRequest { publicRequest() => Messages = new List<string>();
publicobject Data { get; set; } public List<string> Messages { get; set; } }
publicclassPerson { publicstring Name { get; set; } publicint Age { get; set; } }
Create the handler interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14
publicinterfaceIHandler { ///<summary> /// Used to propagate the request to the next handler ///</summary> ///<param name="handler"></param> voidSetNextHandler(IHandler handler); ///<summary> /// Process the request ///</summary> ///<param name="request"></param> voidProcess(Request request); }
publicclassMaxNameLengthHandler : BaseHandler { publicoverridevoidProcess(Request request) { if (request.Data is Person person) { if (person.Name.Length > 10) request.Messages.Add("Invalid Name Length");
if (_nextHandler != null) _nextHandler.Process(request);
return; }
thrownew ArgumentException("Request was not of type Person"); } }
publicclassMaxAgeHandler : BaseHandler { publicoverridevoidProcess(Request request) { if (request.Data is Person person) { if (person.Age > 55) request.Messages.Add("Invalid Age");
if (_nextHandler != null) _nextHandler.Process(request);
return; }
thrownew ArgumentException("Request was not of type Person"); } }
Now test the code. The call(s) to SetNextHandler are admittedly clunky, each handler will need to be setup manually like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
var person = new Person() { Name = "Carl Brown Paton", Age = 84 };
var request = new Request() { Data = person };
var maxNameLengthHandler = new MaxNameLengthHandler(); var maxAgeHandler = new MaxAgeHandler();