- •Предисловие 15
- •Предисловие
- •От авторов
- •Об авторах
- •Благодарности
- •Принятые в книге обозначения
- •Технические рекомендации
- •Дополнительные ресурсы
- •Глава 1. Введение
- •1.1. Понятие паттерна проектирования
- •Определение
- •Метафора
- •1.2. Формат описания паттернов проектирования
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •1.3. Каталог паттернов проектирования
- •Порождающие
- •Структурные
- •Поведенческие
- •1.4. Техники ООП
- •Фабрика - Продукт
- •Фасад - Подсистема
- •Диспетчеризация
- •Цепочка объектов
- •Издатель-Подписчик
- •1.5. Принципы организации каталога
- •Цель паттерна
- •Уровень паттерна
- •1.6. Рекомендации по изучению паттернов
- •1.7. Рекомендации по применению паттернов
- •Глава 2. Порождающие паттерны
- •Игра - Лабиринт
- •Паттерн Abstract Factory
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Builder
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Factory Method
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Prototype
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Паттерн Singleton
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода игры «Лабиринт»
- •Известные применения паттерна в .Net
- •Глава 3. Структурные паттерны
- •Паттерн Adapter
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Adapter уровня классов
- •Adapter уровня объектов
- •Структура паттерна на языке C#
- •Adapter уровня классов
- •Adapter уровня объектов
- •Участники
- •Отношения между участниками
- •Отношения между классами (для адаптера уровня классов)
- •Отношения между классами (для адаптера уровня объектов)
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Adapter уровня классов
- •Adapter уровня объектов
- •Особенности применения паттерна Adapter
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Bridge
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Composite
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Decorator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Facade
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Flyweight
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Proxy
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Глава 4. Паттерны поведения
- •Паттерн Chain of Responsibility
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Command
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн Interpreter
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Паттерн Iterator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Классическое представление
- •Представление Microsoft .NET
- •Структура паттерна на языке C#
- •Классическое представление
- •Представление Microsoft .NET
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Паттерн Mediator
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Паттерн Memento
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Реализация
- •Паттерн Observer
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Модель вытягивания (Pull model)
- •Модель проталкивания (Push model)
- •Структура паттерна на языке C#
- •Модель вытягивания (Pull model)
- •Модель проталкивания (Push model)
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Реализация
- •Пример кода
- •Известные применения паттерна в .Net
- •Паттерн State
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Мотивация
- •Применимость паттерна
- •Результаты
- •Паттерн Strategy
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Паттерн Template Method
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Результаты
- •Реализация
- •Паттерн Visitor
- •Название
- •Также известен как
- •Классификация
- •Частота использования
- •Назначение
- •Введение
- •Структура паттерна на языке UML
- •Структура паттерна на языке C#
- •Участники
- •Отношения между участниками
- •Отношения между классами
- •Отношения между объектами
- •Применимость паттерна
- •Результаты
- •Реализация
- •Известные применения паттерна в .Net
- •Библиография
175
Паттерн Command
Название
Команда
Также известен как
Action (Действие), Transaction (Транзакция)
Классификация
По цели: поведенческий По применимости: к объектам
Частота использования
Выше средней - 1 2 3 4 5
Назначение
Паттерн Command – позволяет представить запрос в виде объекта, позволяя клиенту конфигурировать запрос (задавая параметры для его обработки), ставить запросы в очередь, протоколировать запросы, а также поддерживать отмену операций.
Введение
В качестве примера системы, в которой возможно использовать паттерн Command предлагается рассмотреть упрощенный программный калькулятор с четырьмя арифметическими операциями Add, Sub, Mul, Div и двумя операциями Undo и Redo. Структурная схема калькулятора показана на рисунке ниже.
Вструктуре калькулятора можно выделить UI (наборное поле с кнопками для цифр, знаков отмены
иповтора операций, а также панель для отображения результата). В «корпусе» калькулятора расположены программные блоки, обеспечивающие реакцию калькулятора на поток внешних дискретных событий. Такими событиями являются нажатия кнопок наборного поля.
Состав программных блоков калькулятора, следующий:
176
УУ - Устройство управления (ControlUnit). Оно организует всю работу калькулятора, выдавая в подходящий момент элементарные объекты-команды типа: Add, Sub, Mul, Div, Undo, Redo. При этом УУ сохраняет историю использования команд, а также может отменять и восстанавливать ранее выполненные команды.
АУ - Арифметическое устройство (ArithmeticUnit). После получения «сигнала» (одной из четырех команд Add, Sub, Mul, Div) на вход выполняет арифметическую операцию.
Команды - Add, Sub, Mul, Div. Специальные объекты-команды, которые УУ использует для управления АУ. Каждый объект-команда связан с АУ и умеет правильно им управлять.
Предлагается рассмотреть диаграмму классов на которой представлена модель калькулятора.
См. Пример к главе: \014_Command\002_Command_Undo_Redo
177
Ниже представлен пример реализации калькулятора.
// "Command"
abstract class Command
{
protected ArithmeticUnit unit; protected int operand;
public abstract void Execute(); public abstract void UnExecute();
}
Add
// "ConcreteCommand" class Add : Command
{
public Add(ArithmeticUnit unit, int operand)
{
this.unit = unit; this.operand = operand;
}
public override void Execute()
{
unit.Run('+', operand);
}
public override void UnExecute()
{
unit.Run('-', operand);
}
}
Sub
// "ConcreteCommand" class Sub : Command
{
public Sub(ArithmeticUnit unit, int operand)
{
this.unit = unit; this.operand = operand;
}
public override void Execute()
{
unit.Run('-', operand);
}
public override void UnExecute()
{
unit.Run('+', operand);
}
}
Div
// "ConcreteCommand" class Div : Command
{
public Div(ArithmeticUnit unit, int operand)
{
this.unit = unit; this.operand = operand;
}
public override void Execute()
{
unit.Run('/', operand);
}
public override void UnExecute()
{
unit.Run('*', operand);
}
}
Mul
// "ConcreteCommand" class Mul : Command
{
public Mul(ArithmeticUnit unit, int operand)
{
this.unit = unit; this.operand = operand;
}
public override void Execute()
{
unit.Run('*', operand);
}
public override void UnExecute()
{
unit.Run('/', operand);
}
}
См. продолжение примера на следующей странице.
class Program |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
static void Main() |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
var calculator = new Calculator(); |
|
|
|||||
int result = 0; |
|
|
|
|
|
||
result = |
calculator.Add(5); |
|
|
|
|
|
|
Console.WriteLine(result); |
|
|
|
|
|
||
result = |
calculator.Sub(3); |
|
|
|
|
|
|
Console.WriteLine(result); |
|
|
|
|
|
||
result = calculator.Undo(2); |
|
|
|
|
|
||
Console.WriteLine(result); |
|
|
|
|
|
||
result = |
calculator.Redo(1); |
|
|
|
|
|
|
Console.WriteLine(result); |
|
|
|
|
|
||
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
Калькулятор |
|
|
|
|
// "Client" |
|
|
Команды для АУ |
|
|
|
|
class Calculator |
|
|
Add |
|
Sub |
Div |
Mu l |
{ |
|
|
|
|
|
|
|
ArithmeticUnit arithmeticUnit; |
|
|
|
|
|
||
ControlUnit controlUnit; |
|
УУ |
|
|
АУ |
||
|
|
|
устройство |
||||
|
|
|
Устро йство управления |
|
Ари фметическое |
||
|
|
|
|
|
|||
public Calculator() |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
arithmeticUnit |
= new ArithmeticUnit(); |
|
|||||
controlUnit = |
new ControlUnit(); |
|
|
|
|
||
} |
|
|
|
|
|
|
|
private int Run(Command command) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
controlUnit.StoreCommand(command); |
|
|
|
||||
controlUnit.ExecuteCommand(); |
|
|
|
|
|
||
return arithmeticUnit.Register; |
|
|
|
|
|||
} |
|
|
|
|
|
|
|
public int Add(int operand) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
return Run(new Add(arithmeticUnit, operand)); |
|||||||
} |
|
|
|
|
|
|
|
public int Sub(int operand) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
return Run(new Sub(arithmeticUnit, operand)); |
|||||||
} |
|
|
|
|
|
|
|
public int Mul(int operand) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
return Run(new Mul(arithmeticUnit, operand)); |
|||||||
} |
|
|
|
|
|
|
|
public int Div(int operand) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
return Run(new Div(arithmeticUnit, operand)); |
|||||||
} |
|
|
|
|
|
|
|
public int Undo(int levels) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
controlUnit.Undo(levels); |
|
|
|
|
|
||
return arithmeticUnit.Register; |
|
|
|
|
|||
} |
|
|
|
|
|
|
|
public int Redo(int levels) |
|
|
|
|
|
||
{ |
|
|
|
|
|
|
|
controlUnit.Redo(levels); |
|
|
|
|
|
||
return arithmeticUnit.Register; |
|
|
|
|
|||
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
178
|
УУ |
|
// "Invoker" (Инициатор) |
Устройство |
|
управления |
||
// Устройство управления (УУ) |
||
|
||
class ControlUnit |
|
|
{ |
|
|
private List<Command> commands = |
|
|
new List<Command>(); |
||
private int current = 0; |
|
|
public void StoreCommand(Command command) |
||
{ |
|
|
commands.Add(command); |
|
|
} |
|
|
public void ExecuteCommand() |
|
|
{ |
|
|
commands[current].Execute(); |
|
|
current++; |
|
|
} |
|
|
public void Undo(int levels) |
|
|
{ |
|
|
for (int i = 0; i < levels; i++) |
|
|
if (current > 0) |
|
|
commands[--current].UnExecute(); |
||
} |
|
|
public void Redo(int levels) |
|
|
{ |
|
|
for (int i = 0; i < levels; i++) |
|
|
if (current < commands.Count - |
1) |
|
commands[current++].Execute(); |
||
} |
|
|
} |
|
|
|
|
АУ |
|
|
|
Арифметическое |
||
// "Receiver" (Получатель) |
|
устройство |
||
// Арифметическое устройство (АУ) |
||||
|
|
|||
class ArithmeticUnit |
|
|
|
|
{ |
|
|
|
|
public int Register { get; |
private set; |
} |
||
public void Run(char operationCode, int operand) |
||||
{ |
|
|
|
|
switch (operationCode) |
|
|
|
|
{ |
|
|
|
|
case '+': |
|
|
|
|
Register += operand; |
|
|
||
break; |
|
|
|
|
case '-': |
|
|
|
|
Register -= operand; |
|
|
||
break; |
|
|
|
|
case '*': |
|
|
|
|
Register *= operand; |
|
|
||
break; |
|
|
|
|
case '/': |
|
|
|
|
Register /= operand; |
|
|
||
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
См. Пример к главе: \014_Command\002_Command_Undo_Redo