/* Цепочка обязанностей Избегает связывание отправителя запроса с его получателем, давая возможность обработать запрос более чем одному объекту. Связывает объекты-получатели и передаёт запрос по цепочке пока объект не обработает его. */ class Program { public static void GiveCommand(IWorker worker, string command) { var str = worker.Execute(command); if(string.IsNullOrEmpty(str)) Console.WriteLine(command + " - никто не выполнил команду"); else Console.WriteLine(str); } static void Main() { #region Пример №1 - базовое Handler h1 = new ConcreateHandler1(); Handler h2 = new ConcreateHandler2(); h1.Successor = h2; h1.HandleRequest(2); //От первого до второго объекта обработка Console.WriteLine("Please press Enter..."); Console.ReadKey(); #endregion #region Пример №2 - этапы строительства дома var designer = new Designer(); var programmer = new Programmer(); var finishworker = new FinishWorker(); designer.SetNetWorker(finishworker).SetNetWorker(programmer); GiveCommand(designer, "Спроектировать веранду"); GiveCommand(designer, "Сделать машину времени"); GiveCommand(designer, "Уволить работников"); GiveCommand(designer, "Курить"); #endregion } } /// /// Передатчик /// abstract class Handler { public Handler Successor { get; set; } public abstract void HandleRequest(int condition); } /// /// Обработчик запроса №1 /// class ConcreateHandler1 : Handler { /// /// Обработка запроса /// /// состояние public override void HandleRequest(int condition) { Console.WriteLine("1"); if(condition == 1) return; //завершаем выполнение else if(Successor != null) Successor.HandleRequest(condition); //передача запроса дальше по цепи } } /// /// Обработчик запроса №2 /// class ConcreateHandler2 : Handler { /// /// Обработка запроса /// /// состояние public override void HandleRequest(int condition) { Console.WriteLine("2"); if (condition == 2) return; //завершаем выполнение else if (Successor != null) //передача запроса дальше по цепи Successor.HandleRequest(condition); } } /// /// Поведение рабочего /// interface IWorker { /// /// Передача обязанностей следующему рабочему /// /// следующий рабочий IWorker SetNetWorker(IWorker worker); /// /// Рабочий принимает команду на исполнение /// /// команда /// Резульат принятия string Execute(string command); } /// /// Абстрактный рабочий, базовое описание структуры каждого /// abstract class AbsWorker : IWorker { private IWorker nextWorker; public AbsWorker() => nextWorker = null; /// /// Изменяемый процесс обработки команды в классах наследниках /// У каждого рабочего свой процесс выполнени /// /// команда /// Результат public virtual string Execute(string command) { if (nextWorker == null) return string.Empty; return nextWorker.Execute(command); } /// /// Передача обязанностей другому рабочему /// /// Другой рабочий /// Другой рабочий public IWorker SetNetWorker(IWorker worker) { nextWorker = worker; return worker; } } class Designer : AbsWorker { public override string Execute(string command) { if (command == "Спроектировать веранду") return "Проектировщик выполнил команду: " + command; else return base.Execute(command); //если не может выполнить передаёт следующему в цепочке } } class Programmer: AbsWorker { public override string Execute(string command) { if(command == "Сделать машину времени") return "Программист выполнил команду: " + command; else return base.Execute(command); } } class FinishWorker : AbsWorker { public override string Execute(string command) { if (command == "Уволить работников") return "Начальник выполнил команду: " + command; else return base.Execute(command); } }