Chain of responsibility или Цепочка обязанностей
из wiki
Шаблон рекомендован для использования в условиях:
- в разрабатываемой системе имеется группа объектов, которые могут обрабатывать сообщения определенного типа;
- все сообщения должны быть обработаны хотя бы одним объектом системы;
- сообщения в системе обрабатываются по схеме «обработай сам либо перешли другому», то есть одни сообщения обрабатываются на том уровне, где они получены, а - другие пересылаются объектам иного уровня.
Если по простому, то данный шаблон, это набор неких блоков которые последовательно обрабатывают входящие данные.
Рассмотрим реализацию данного шаблона на примере создания механизма логирования.
Всякие плюшки на подобии имплементации интерфейсов или наследования классов будет реализоваваться через явную связь обработок.
Принцип применен тот же, чито в шаблоне Decorator.
Создаем интерфейс, в нем объявляются 2 метода УстановитьHandler и СделатьЗаписьЛога
Создаем 2 класса для логирования в журнал регистрации и для логирования в регистр
Реквизит Handler имеет тип ЛогированиеИнтерфейс, абстракция однако.
УровеньЛогирования - число, это тот уровень при котором будет текущий логер писать данные.
Применение такое:
// Уровни логирования
// 1 - инфо.
// 2 - Предупреждения.
// 3 - Ошибка.
Логирование = Обработки.ЛогированиеЖР.Создать().Конструктор(2).Имплементация("ЛогированиеИнтерфейс");
ЛогированиеРегистр = Обработки.ЛогированиеРегистр.Создать()
.Конструктор(3)
.Имплементация("ЛогированиеИнтерфейс");
Логирование.УстановитьHandler(ЛогированиеРегистр);
Данные = Новый Структура("Сообщение, УровеньЛогирования", "Проверка предупреждения", 2);
Логирование.СделатьЗаписьЛога(Данные);
Данные = Новый Структура("Сообщение, УровеньЛогирования", "Проверка ошибки", 3);
Логирование.СделатьЗаписьЛога(Данные);
через УстановитьHandler мы добавляем в очередь логеры, которые последовательно будут обрабатывать методы.
переменная Логирование - это так же интерфейс
кстати, этот код можно вынести в какой-нибудь общий модуль
Логирование = Обработки.ЛогированиеЖР.Создать().Конструктор(2).Имплементация("ЛогированиеИнтерфейс");
ЛогированиеРегистр = Обработки.ЛогированиеРегистр.Создать()
.Конструктор(3)
.Имплементация("ЛогированиеИнтерфейс");
Логирование.УстановитьHandler(ЛогированиеРегистр);
Какой профит мы получаем при таком подходе, каждый логер это отдельный алгоритм сохранение записи (ЖР, Файл, СМС и прочее), в коде мы просто задаем уровень к которому относится тек. запись
Данные = Новый Структура("Сообщение, УровеньЛогирования", "Проверка ошибки", 3);
Логирование.СделатьЗаписьЛога(Данные);
далее уже определяется в самом логере, мое это или нет, если нет, передаем дальше.
Картина получается такая
Кстати. при большом желании можно вообще сделать регистр для хранение логеров и подключать их динамически, там же настраивать уровень логирования который будет обрабатывать логер.