/* Цепочка обязанностей
Избегает связывание отправителя запроса
с его получателем, давая возможность обработать
запрос более чем одному объекту. Связывает
объекты-получатели и передаёт запрос по цепочке
пока объект не обработает его.
*/
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);
}
}