namespaceRefactoringGuru.DesignPatterns.ChainOfResponsibility.Conceptual { // The Handler interface declares a method for building the chain of // handlers. It also declares a method for executing a request. publicinterfaceIHandler { IHandler SetNext(IHandler handler);
objectHandle(object request); }
// The default chaining behavior can be implemented inside a base handler // class. abstractclassAbstractHandler : IHandler { private IHandler _nextHandler;
public IHandler SetNext(IHandler handler) { this._nextHandler = handler;
// Returning a handler from here will let us link handlers in a // convenient way like this: // monkey.SetNext(squirrel).SetNext(dog); return handler; }
classClient { // The client code is usually suited to work with a single handler. In // most cases, it is not even aware that the handler is part of a chain. publicstaticvoidClientCode(AbstractHandler handler) { foreach (var food innew List<string> { "Nut", "Banana", "Cup of coffee" }) { Console.WriteLine($"Client: Who wants a {food}?");
var result = handler.Handle(food);
if (result != null) { Console.Write($" {result}"); } else { Console.WriteLine($" {food} was left untouched."); } } } }
classProgram { staticvoidMain(string[] args) { // The other part of the client code constructs the actual chain. var monkey = new MonkeyHandler(); var squirrel = new SquirrelHandler(); var dog = new DogHandler();
monkey.SetNext(squirrel).SetNext(dog);
// The client should be able to send a request to any handler, not // just the first one in the chain. Console.WriteLine("Chain: Monkey > Squirrel > Dog\n"); Client.ClientCode(monkey); Console.WriteLine();
Client: Who wants a Nut? Squirrel: I'll eat the Nut. Client: Who wants a Banana? Monkey: I'll eat the Banana. Client: Who wants a Cup of coffee? Cup of coffee was left untouched.
Subchain: Squirrel > Dog
Client: Who wants a Nut? Squirrel: I'll eat the Nut. Client: Who wants a Banana? Banana was left untouched. Client: Who wants a Cup of coffee? Cup of coffee was left untouched.