
- •А.А. Волосевич
- •3. Шаблоны и архитектура программ
- •3.1. Модульное тестирование
- •3.2. Шаблоны проектирования
- •3.3. Структурные шаблоны: Декоратор, Заместитель, мост Декоратор (Decorator)
- •Заместитель (Proxy)
- •Мост (Bridge)
- •3.4. Структурные шаблоны: компоновщик и приспособленец Компоновщик (Composite)
- •Приспособленец (Flyweight)
- •3.5. Структурные шаблоны: адаптер и фасад Адаптер (Adapter)
- •Фасад (Façade)
- •3.6. Порождающие шаблоны: прототип, фабричный метод, одиночка Прототип (Prototype)
- •Фабричный метод (Factory method)
- •Одиночка (Singleton)
- •3.7. Порождающие шаблоны: абстрактная фабрика и строитель Абстрактная фабрика (Abstract factory)
- •Строитель (Builder)
- •3.8. Шаблоны поведения: стратегия, состояние, шаблонный метод Стратегия (Strategy)
- •Состояние (State)
- •Шаблонный метод (Template method)
- •3.9. Шаблоны поведения: цепочка обязанностей и команда Цепочка обязанностей (Chain of responsibility)
- •Команда (Command)
- •3.10. Шаблоны поведения: итератор, посредник, наблюдатель Итератор (Iterator)
- •Посредник (Mediator)
- •Наблюдатель (Observer)
- •3.11. Шаблоны поведения: посетитель, интерпретатор, хранитель Посетитель (Visitor)
- •Интерпретатор (Interpreter)
- •Хранитель (Memento)
- •3.12. Некоторые неклассические шаблоны проектирования
- •Неизменный объект (Immutable object)
- •Пул объектов (Object pool)
- •Отложенная инициализация (Lazy initialization)
- •Нулевой объект (Null object)
- •3.13. Антипаттерны
- •3.14. Архитектура прогРаммного Обеспечения
- •«Клиент-сервер»
- •Архитектура, основанная на использовании компонентов
- •Многоуровневая архитектура
- •Шина сообщений
- •Выделенное представление
- •Объектно-ориентированная архитектура
- •Архитектура, ориентированная на сервисы
Шаблонный метод (Template method)
Предположим, что программная логика некоего алгоритма представлена в виде набора вызовов методов. При использовании Шаблонного метода создается абстрактный класс, который реализует только часть методов программной логики, оставляя детали реализации остальных методов своим потомкам. Благодаря этому общая структура алгоритма остаётся неизменной, в то время как некоторые конкретные шаги могут изменяться.
В качестве иллюстрации применения шаблонного метода рассмотрим класс с методом сортировки. Пусть этот метод вызывает отдельный метод сравнения элементов сортируемого набора. Классы-наследники переопределяют метод сравнения, позволяя, например, реализовать сортировку по убыванию или по возрастанию.
using System;
public abstract class Sorter
{
private readonly int[] data;
protected Sorter(params int[] source)
{
data = new int[source.Length];
Array.Copy(source, data, source.Length);
}
protected abstract bool Compare(int x, int y);
public void Sort()
{
for (var i = 0; i < data.Length - 1; i++)
{
for (var j = i + 1; j < data.Length; j++)
{
if (Compare(data[j], data[i]))
{
var temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
public int[] GetData()
{
var result = new int[data.Length];
Array.Copy(data, result, data.Length);
return result;
}
}
public class GreaterFirstSorter : Sorter
{
public GreaterFirstSorter(params int[] source) : base(source){ }
protected override bool Compare(int x, int y)
{
return x > y;
}
}
public class TemplateMethodExample
{
private static void Main()
{
var sorter = new GreaterFirstSorter(1, 3, -10, 0);
sorter.Sort();
var result = sorter.GetData();
}
}
3.9. Шаблоны поведения: цепочка обязанностей и команда Цепочка обязанностей (Chain of responsibility)
Шаблон Цепочка обязанностей работает со списком объектов, называемых обработчиками. Каждый из обработчиков имеет естественные ограничения на множество запросов, которые он в состоянии поддержать. Если текущий обработчик не может поддержать запрос, он передает его следующему обработчику в списке. Так продолжается, пока запрос не будет обработан, или пока список не закончится.
Иллюстрацией шаблона Цепочка обязанностей может служить любая организация с иерархической структурой управления. Представим себе банк, в который клиент обращается за кредитом. Если сумма кредита небольшая, запрос удовлетворяет служащий нижнего звена банка. В противном случае запрос отправляется на более высокий уровень иерархии управления.
Дизайн шаблона Цепочка обязанностей достаточно прост. Каждый из обработчиков принадлежит к одному из классов, имеющих общего предка или реализующих общий интерфейс. Кроме метода (или методов) для обработки запроса обработчик имеет поле, указывающее следующий обработчик в цепочке.
Рис. 18. UML-диаграмма шаблона Цепочка обязанностей.
Ниже приведён код, иллюстрирующий применение шаблона Цепочка обязанностей.
using System;
public class Handler
{
private readonly Handler next;
private readonly int id;
public int Limit { get; private set; }
public Handler(int id, Handler handler)
{
this.id = id;
Limit = id * 1000;
next = handler;
}
public string HandleRequest(int data)
{
if (data < Limit)
{
return string.Format(
"Request for {0} handled at level {1}", data, id);
}
return next != null
? next.HandleRequest(data)
: string.Format(
"Request for {0} handled BY DEFAULT at level {1}", data, id);
}
}
public class ChainOfResponsibilityExample
{
private static void Main()
{
Handler start = null;
for (var i = 5; i > 0; i--)
{
Console.WriteLine(
"Handler {0} deals up to a limit of {1}", i, i * 1000);
start = new Handler(i, start);
}
int[] a = { 50, 2000, 1500, 10000, 175, 4500 };
foreach (var i in a)
{
Console.WriteLine(start.HandleRequest(i));
}
}
}