
- •Предисловие 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
- •Библиография
186
Пример кода
Рассмотрим детальнее конкретные классы команд из раздела Мотивация. Класс OpenCommand, реализует команду открытия документа выбранного пользователем в приложении, используя метод AddDocument класса MainForm и реализуя абстрактный метод Execute родительского абстрактного класса
Command:
class OpenCommand : Command
{
public override void Execute()
{
var filename = AskUser();
if (!string.IsNullOrEmpty(filename))
{
var doc = new Document(); doc.Open(filename); LogExecution(" opened");
MainForm.MainFormInstance.AddDocument(doc);
}
else
{ LogExecution(" opening cancelled"); }
}
string AskUser()
{
LogExecution("Asking user."); var dlg = new OpenFileDialog();
dlg.InitialDirectory = Application.StartupPath; if (dlg.ShowDialog() == DialogResult.OK)
{
return dlg.FileName;
}
else
return string.Empty;
}
}
public partial class MainForm : Form
{
internal static Document CurrentDocument { get; set; }
internal static MainForm MainFormInstance { get; private set; }
public MainForm()
{
InitializeComponent(); toolStripMenuItem1.DropDownItems.AddRange(new ToolStripItem[] {
new MyMenuItem("Open",new OpenCommand()), new MyMenuItem("Close",new CloseCommand()), new ToolStripSeparator(),
new MyMenuItem("Cut",new CutCommand()), new MyMenuItem("Copy",new CopyCommand()),
new MyMenuItem("Paste",new PasteCommand()), new ToolStripSeparator(),
new MyMenuItem("MacroCopy",new MacroCommand(new OpenCommand(),
new SelectAllTextCommand(), new CopyCommand(),
new CloseCommand()))
});
MainFormInstance = this;
}
private void AddMenuItemWithTemplateCommands()
{
187
toolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { toolStripMenuItem2});
toolStripMenuItem2.Name = "toolStripMenuItem2"; toolStripMenuItem2.Size = new System.Drawing.Size(106, 20); toolStripMenuItem2.Text = "DocumentTemplate Menu";
toolStripMenuItem2.DropDownItems.AddRange(new ToolStripItem[] {
new MyMenuItem("Cut",new SimpleCommand(CurrentDocument.Cut,"cut")),
new MyMenuItem("Copy",new SimpleCommand(CurrentDocument.Copy, "copy")), new MyMenuItem("Paste",new SimpleCommand(CurrentDocument.Paste,"paste")),
});
}
public void AddDocument(Document document)
{
document.MdiParent = this; document.Show();
AddMenuItemWithTemplateCommands();
}
public void Log(string logString)
{
logLabel.Text += Environment.NewLine + logString;
}
}
Классы CloseCommand, CopyCommand, CutCommand, PasteCommand, SelectAllTextCommand и MacroCommand аналогично реализуют соответственно закрытие документа, копирование и вырезание выделенного фрагмента текста, вставку текста из буфера обмена, выделение всего текстового содержимого в документе и заданную в коде приложения последовательность команд.
class CloseCommand : Command
{
public override void Execute()
{
if (MainForm.CurrentDocument != null)
{
LogExecution("close"); MainForm.CurrentDocument.Close();
}
}
}
class CopyCommand : Command
{
public override void Execute()
{
if (MainForm.CurrentDocument != null)
{
LogExecution("copy text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); MainForm.CurrentDocument.Copy();
}
}
}
class CutCommand : Command
{
public override void Execute()
{
188
if (MainForm.CurrentDocument != null)
{
LogExecution("cut text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); MainForm.CurrentDocument.Cut();
}
}
}
class PasteCommand : Command
{
public override void Execute()
{
if (MainForm.CurrentDocument != null)
{
LogExecution("paste text: " + Clipboard.GetText()); MainForm.CurrentDocument.Paste();
}
}
}
class SelectAllTextCommand : Command
{
public override void Execute()
{
if (MainForm.CurrentDocument != null)
{
LogExecution(MainForm.CurrentDocument.Text + "select all text"); MainForm.CurrentDocument.DocumentContent.SelectAll();
}
}
}
class MacroCommand : Command
{
public readonly List<Command> Commands = new List<Command>();
public MacroCommand(params Command[] commands)
{
Commands.AddRange(commands);
}
public override void Execute()
{
foreach (var c in Commands) c.Execute();
}
}
Заметим, что класс MacroCommand не содержит ссылок на объекты-исполнители запросов, т.к. они инкапсулированы в объектах типа Command, набор которых хранит в себе данный класс.
class SimpleCommand : Command
{
Action action; string actionKeyword;
public SimpleCommand(Action action, string actionKeyword)
189
{
this.action = action; this.actionKeyword = actionKeyword;
}
public override void Execute()
{
if (action != null)
{
LogExecution(actionKeyword + " text: " + MainForm.CurrentDocument.DocumentContent.SelectedText); action.Invoke();
}
}
}
В классе SimpleCommand каждая связка «объект-исполнитель – действие» задается делегатом типа Action при вызове конструктора класса, а объекты класса SimpleCommand оперируют только ссылкой на необходимый callback метод, который передан с делегатом класса Action.
Известные применения паттерна в .Net
System.Data.Odbc.OdbcCommand http://msdn.microsoft.com/ru-ru/library/system.data.odbc.odbccommand(v=vs.110).aspx
System.Data.OleDb.OleDbCommand http://msdn.microsoft.com/ru-ru/library/system.data.oledb.oledbcommand(v=vs.110).aspx
System.Data.OracleClient.OracleCommand http://msdn.microsoft.com/en-us/library/system.data.oracleclient.oraclecommand(v=vs.110).aspx
System.Data.SqlClient.SqlCommand http://msdn.microsoft.com/ru-ru/library/system.data.sqlclient.sqlcommand(v=vs.100).aspx
System.Windows.Input.ICommand http://msdn.microsoft.com/en-us/library/system.windows.input.icommand(v=vs.110).aspx
System.Windows.Input.ComponentCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.componentcommands(v=vs.110).aspx
System.Windows.Input.MediaCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.mediacommands(v=vs.110).aspx
System.Windows.Input.NavigationCommands http://msdn.microsoft.com/ru-ru/library/system.windows.input.navigationcommands(v=vs.110).aspx
System.Windows.Input.RoutedCommand http://msdn.microsoft.com/ru-ru/library/system.windows.input.routedcommand(v=vs.110).aspx
System.Windows.SystemCommands http://msdn.microsoft.com/ru-ru/library/system.windows.systemcommands(v=vs.110).aspx
System.Workflow.ComponentModel.Design.WorkflowMenuCommands http://msdn.microsoft.com/ruru/library/system.workflow.componentmodel.design.workflowmenucommands(v=vs.110).aspx