SlideShare a Scribd company logo
1 of 236
Download to read offline
УК 03.003.01-2011
Учебный курс. Обучение.
Шаблоны ОО проектирования.
Определение паттерна
Паттерн проектирования – описание взаимодействия
классов и объектов, адаптированных для решения
задачи проектирования в конкретном контексте.
• Кристофер Александр, 1977 для архитектуры
• Паттерн – это не готовый к использованию набор классов,
а лишь описание способа решения конкретной задачи.
• Тригонометрическая подстановка для решения интеграла.
Шаблон описания паттерна
•
•
•
•
•
•
•
•
•
•
•
•
•

Название и классификация паттерна
Назначение
Имя синоним
Мотивация
Применимость
Структура
Участники
Отношения
Результаты
Реализация
Пример кода
Известные применения
Родственные паттерны
Абстрактная фабрика
Категория: паттерн, порождающий объекты
Назначение: Определяет интерфейс для создания набора
взаимосвязанных или взаимозависимых объектов, так что
клиент не знает о точных классов, используемых им
объектов.
Имя синоним: Kit (Инструментарий)
Мотивация
• Чтобы создать объект, надо явно указать имя класса,
экземпляром которого будет объект.
• Имя класса в тексте программы – потенциальный
источник нарушения принципа подстановки Лисков и
открыто-замкнутого принципа
• Отказаться от упоминания имен класса в тексте
программы невозможно, следовательно их
использование должно быть максимально локализовано.
• Идеальный вариант – имя класса упоминается лишь один
раз во всем тексте программы, что избежать проблемы
Copy-Paste
• AbstractProductA CreateProductA() – метод инкапсулирует в
себе создание экземпляра ProductA, нам доступен лишь
интерфейс базового класса. Такой подход удовлетворяет
принципу подстановки Лисков.
• Как компоновать методы, создающие объекты?
• Есть классы сильно сцепленные между собой, а есть –
независимые.
• Объединим методы, создающие сильно сцепленные
объекты между собой в один класс (обобщенный принцип
повторного использования, обобщенный принцип
замкнутости)
• Согласно принципу единственной ответственности
каждый класс должен заниматься выполнением только
одной операции.
• Должен быть класс, единственной задачей которого
является создание экземпляров сильно сцепленных
между собой классов.
Применимость:
• необходимо обеспечить замкнутость относительно
создания, компоновки и представления входящих в нее
объектов (способ создания объекта скрыт за вызываемым
методом);
• Необходимо обеспечить ограничение – взаимосвязанные
объекты должны использоваться вместе (реализации File,
Directory);
• Необходимо обеспечить конфигурирование одним из
семейств классов (Работа через протокол Tcp, Udp);
• Необходимо раскрыть только интерфейсы, реализация
должна быть закрыта.
Структура
Отношения
• Во время выполнения создается единственный экземпляр
класса ConcreteFactory, который создает определенные
объекты-продукты. Для создания объектов-продуктов с
другой реализацией клиент должен создать экземпляр
другой конкретной фабрики.
• Абстрактная фабрика делегирует создание объектов
продуктов конкретной фабрике.
Результат
• Стратегическая замкнутость:
– Клиентский код не зависит от конкретных классов
продуктов.
• Замкнутость не обеспечивается для:
– Добавления новых видов продуктов.
• Побочные эффекты:
– Упрощает замену семейств продуктов;
– Гарантия сочетаемости продуктов.
Вопросы реализации
• Фабрика как Singleton
• Создание продукта:
– Фабричный метод
– Прототип

• Расширяемые фабрики
– Использование сборок
– Распределенная фабрика (COM, процедура инициализация DLL)
Пример 04.001.01-2011
• Интерфейсы выделены в отдельную фабрику
• Главное приложение явно зависит только от интерфейсов
• Выбор семейства классов можно настраивать из файла
конфигурации.
• Фабрикой закрываются только те классы, которые
находятся за пределами текущего модуля. Если надо
инстанцировать класс, который находится внутри данного
модуля, то его имя можно использовать напрямую.
Принцип эквивалентности единицы повторного
использования и единицы релиза!!!
Известные применения
• System.DataCommon.DbProviderFactory (ADO .Net)
static DbConnection CreateDbConnection( string providerName, string connectionString)
{
DbConnection connection = null;
if (connectionString != null)
{
try
{
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
}
catch (Exception ex)
{
if (connection != null)
{
connection = null;
}
Console.WriteLine(ex.Message);
}
}
return connection;
}
Методы DbProviderFactory
•
•
•
•
•
•
•
•

CreateCommand Возвращает новый экземпляра класса поставщика, реализующий класс DbCommand.
CreateCommandBuilder Возвращает новый экземпляра класса поставщика, реализующий класс DbCommandBuilder.
CreateConnection Возвращает новый экземпляра класса поставщика, реализующий класс DbConnection.
CreateConnectionStringBuilder Возвращает новый экземпляра класса поставщика, реализующий класс DbConnectionStringBuilder.
CreateDataAdapter Возвращает новый экземпляра класса поставщика, реализующий класс DbDataAdapter.
CreateDataSourceEnumerator Возвращает новый экземпляра класса поставщика, реализующий класс DbDataSourceEnumerator.
CreateParameter Возвращает новый экземпляра класса поставщика, реализующий класс DbParameter.
CreatePermission Возвращает новый экземпляра класса поставщика, реализующий версию поставщика класса CodeAccessPermission.
Родственные паттерны
• Фабричный метод
• Прототип
• Одиночка
Строитель
Категория: паттерн, порождающий объекты
Назначение: Отделяет алгоритм конструирования сложного
объекта от его представления, так что в результате одного
и того же процесса конструирования могут получаться
совершенно разные представления.
Мотивация
• Предположим, что процесс инициализации объекта
происходит не в одно действие
• Часто это является причиной для использования
конструктора с пустым набором параметров и
инициализации объекта через набор полей
Например, HTTP/FTP запрос или ответ
1. Указать заголовки
2. Указать URL запроса
3. Задать тело запроса (если есть).
private void RegisterFile(Guid guid, String fileExt)
{
using (SqlConnection connection = new
SqlConnection(connectionString))
{
SqlCommand dbCommand = new
SqlCommand("mm_File_Register", connection);
dbCommand.CommandType = CommandType.StoredProcedure;
dbCommand.Parameters.Add(new SqlParameter("guid",
SqlDbType.UniqueIdentifier));
dbCommand.Parameters.Add(new SqlParameter("storage_path",
SqlDbType.VarChar, 50));
dbCommand.Parameters.Add(new SqlParameter("profile_name",
SqlDbType.VarChar, 256));
dbCommand.Parameters.Add(new SqlParameter("file_ext",
SqlDbType.VarChar, 256));
dbCommand.Parameters["guid"].Value = guid;
dbCommand.Parameters["storage_path"].Value =
FileStorage.BasePath;
dbCommand.Parameters["profile_name"].Value = profile;
dbCommand.Parameters["file_ext"].Value = fileExt; // Image
dbCommand.Connection.Open();
dbCommand.ExecuteNonQuery();
dbCommand.Connection.Close();
}
}

private bool ConvertOriginal(Stream original, out byte[] bytes)
{
Image image;
var origBytes = ReadAllBytes(original);
using (var origStream = new MemoryStream(origBytes))
{
try { image = Image.FromStream(origStream); }
catch (ArgumentException ex) { throw new
BadImageException(ex); }
var format = ImageFormat.OriginalImageFormat(image);
if (format == null)
{
bytes = origBytes;
return false;
}
else
{
var convBytes = ImageConverter.Convert(origStream, format);
if (convBytes.Length < origBytes.Length) { bytes = convBytes;
return true; }
else { bytes = origBytes; return false; }
}
}
}
Замечания к примеру
• Нарушение принципа единственной ответственности
– Создаем хранилище
– Преобразование графических данных к указанному формату
– Файл с неграфическими данными сохраняется в хранилище под
именем “f” c текущим расширением, возможно, здесь добавлено
поведение, что может быть только один файл для каждого
расширения, а может быть имя файла не так важно, а важен guid, под
котором файл зарегистрирован в базе данных

• Преобразование графического изображения идет после
сохранения в хранилище первого варианта, значит два раза
пишем на ftp сервер
• Получение расширения по имени файла
• Отсутствие транзакционности (можно зарегистрировать файл,
но при этом не записать его в хранилище)
• Раз объект нельзя проинициализировать в одно действие, то,
либо структура объекта сложная (например, составной объект),
либо данные, необходимые для инициализации нельзя
получить одномоментно (чтение запроса).
• Если структура объекта сложная, то она либо будет меняться, а
значит и сам алгоритм инициализации, либо будет необходимо
иметь несколько различных реализаций (надо избежать copypaste алгоритма инициализации)
• Если данные нельзя получить одномоментно, то их необходимо
где-то накапливать, чтобы потом создать полностью
проинициализированный объект (контрактная модель).
• Надо отделить вызов конструктора и передачи в него
параметров от алгоритма инициализации.
• Весь алгоритм инициализации разбивается на несколько
шагов.
• Результат каждого шага – изолированная порция
информации, необходимая для корректной
инициализации конечного объекта
• Для примера 2:
–
–
–
–

Подготовка данных к сохранению,
Создать пустой файл
Сохранить данные в файл
Регистрация файла в базе.
Применимость:
• Алгоритм создания сложного объекта не должен зависеть
от того, из каких частей состоит объект и как они
стыкуются между собой;
• Процесс конструирования должен обеспечивать
различные представления конструируемого объекта
Структура
Результаты
•

•

Позволяет изменять внутреннее представление продукта.
Класс Builder предоставляет Director интерфейс для конструирования продукта, за
которым скрывается внутренняя структура продукта, процесс его сборки. Для
повторного использования алгоритма инициализации достаточно лишь
определить нового строителя.
Изолирует код, реализующий конструирование и представление. Улучшает
модульность. Клиенты ничего не знают о классах, определяющих внутреннюю
структуру продукта.
Управление процессом конструирования.

•

Побочные эффекты:

•

–

–
–

Результатом конструирования могут быть совершенно разные объекты, не имеющих между
собой ничего общего.
Например,
1. матрица – либо сама матрица, либо признак – является она диагональной или нет.
2. Алгоритм конвертера – либо обработанные объявления в базе, либо отчет об ошибках в
файл.
Иногда Builder используется для оптимизации производительности (StringBuilder из .Net)
Упрощает применение Mock объектов при организации модульного тестирования
Вопросы реализации
• Интерфейс сборки и конструирования
– Чаще всего Director не требуется доступ к частям конструируемого
объекта, поэтому интерфейс Builder ориентирован только на передачу
параметров в одну сторону от Builder к Director
– Если же Director такой доступ все же необходим, тогда в интерфейс
Builder вводятся методы подсказок о конструируемых частях. Этот
случай специфический, поэтому следует применять с крайней
осторожностью.

• Метод, возвращающий продукт часто бывает не полиморфным,
потому что билдеры могут создавать самые разные продукты,
сильно отличающиеся друг от друга. Класс продукта обычно
жестко привязан к самому билдеру.
• Жирные интерфейсы в билдере нежелательны, но допустимы,
поскольку набор методов обусловлен алгоритмом
инициализации, а не конечным представлением результата
иниуциализации.
Пример 04.002.01-2011
Известные применения
• System.Data.Common.DBConnectionStringBui
lder
• System.Text.StringBuilder
Родственные паттерны
• Абстрактная фабрика
• Компоновщик (как правило строитель используется для
конструирования составных объектов)
Прототип
• Категория: паттерн, порождающий объекты
• Назначение: Задает виды создаваемых объектов с
помощью экземпляра-прототипа и создает новые объекты
путем копирования этого прототипа
Мотивация
• Объявление
Цель: заявить о чем-либо, чтобы получить желаемую
реакцию аудитории
• Форма сообщения
– Зависит от способа доставки сообщения
– Зависит от желания заявителя (например, кредитный калькулятор)

• Способ доставки сообщения до потребителя
• Проспект – каналы доставки сообщений до целевой
аудитории
• Рано или поздно функционал стабилизируется (содержание)
• Начинает меняться форма
Дифференцируйся или умирай! (Джек Траут)
MS Office, MS Windows
Дизайн Город55
• Внутренняя структура усложняется, часто нет никаких разумных
объяснений той или иной структуре
Например, необработанные объявления в виде текстовой строки
• Создание классов становится неоправданно дорогим
• Лучше конфигурировать систему особым образом
проинициализированными объектами
Например, объявление – структуру полей можно взять из
конвертора
Применимость
• Инстанцируемые классы определяются во время
выполнения
• Для того, чтобы избежать построения иерархий классов
или фабрик, параллельных иерархии классов продуктов
• Экземпляры класса могут находится в одном из не очень
большого числа различных состояний. Может оказаться
удобнее установить соответствующее число прототипов и
клонировать их, а не инстанцировать каждый раз класс
вручную в подходящем состоянии.
Структура
Результаты
• Те же, что у абстрактной фабрики и строителя
• Добавление и удаление продуктов во время выполнения
• Спецификация новых объектов путем изменения значений
Вместо нескольких классов, создается несколько объектов одного
класса, отличающихся своим состоянием
Например, объявление
• Спецификация объектов путем изменения структуры
Например, рубрика параметризуется экземпляром объявления,
которое можно подавать в данную рубрику
• Уменьшение числа подклассов
• Динамическое конфигурирование приложения прототипами
Вопросы реализации
• Использование диспетчера прототипов
(ассоциативный массив, хранящий каждый прототип по
ключу)
• Реализация операции Clone
– Поверхностное и глубокое копирование
– IСloneable

• Инициализация клонов
Известные применения
• ArrayList
• Метод MemberwiseClone класса object
Родственные паттерны
• Расширяемая абстрактная фабрика может строиться на
основе прототипов
• Часто применяется там же, где компоновщик и декоратор.
Фабричный метод
• Категория: паттерн, порождающий объекты
• Назначение: Определяет интерфейс для создания
объекта, но оставляет подклассам решение какой класс
инстанцировать.
• Синоним: Виртуальный конструктор
Мотивация
• Идея та же, что и для абстрактной фабрики, только класс, в
котором размещается фабричный метод, существует для
других целей, чем просто создание набора продуктов.
Применимость
• Классу заранее неизвестно, объекты каких классов ему
нужно создавать
• Класс спроектирован так, что чтобы объекты, которые он
создает, специфицировались подклассами
• Класс делегирует обязанности одному из нескольких
вспомогательным классов. Необходимо локализовать
знание о том, какой класс принимает эти обязанности на
себя
(например, для определения стратегий)
Структура
Результаты
• Предоставляет классам операции-зацепки (hooks)
• Соединяет параллельные иерархии
Реализация
• Две основных реализации
– Creator – абстрактный класс
– Creator – конкретный класс

• Параметризованные фабричные методы
• Generic типы, чтобы не порождать подклассы
class Creator<T>
{
T Create()
{
return new T();

}
}

• Extenders .Net можно использовать в качестве фабричных
методов
• Соглашение об именах
Известные применения
• DBConnection
protected abstract DbCommand CreateDBCommand()
• XMLSerialzier.CreateReader
protected virtual XmlSerializationReader CreateReader()
Родственные паттерны
• Абстрактная фабрика часто реализуется с помощью
фабричных методов
• Фабричные методы часто применяются внутри шаблонных
методов, например, для создания стратегий
Синглетон
• Категория: паттерн, порождающий объекты
• Назначение: Гарантирует, что у класса один экземпляр, и
предоставляет к нему глобальную точку доступа.
Мотивация
• Для некоторых классов, важно, чтобы существовал ровно
один экземпляр, например, расширяемая фабрика
• Если использовать глобальную переменную, то придется
явно указывать имя класса, что нарушит открытозамкнутый принцип, кроме того, глобальная переменная
не запрещает создавать другие экземпляры.
• Класс сам должен контролировать количество
экземпляров, которое можно создать.
• Контроль возможно осуществлять только из методов.
Применимость
• Должен быть ровно один экземпляр некоторого класса,
легко доступный всем клиентам;
• Единственный экземпляр должен расширяться путем
порождения подклассов, и клиентам нужно иметь
возможность работать с расширенным экземпляром без
модификации своего кода.
Структура
Результаты
• Контролируемый доступ к единственному экземпляру
• Уменьшение числа имен
• Допускает уточнение операций и представления
• Допускает переменное число экземпляров
• Большая гибкость, чем у операций класса.
Паттерн MonoState. Все поля и методы сделать
статическими, чтобы гарантировать, что есть ровно один
экземпляр. Но тогда нельзя использовать наследование.
Реализация
• Гарантирование одного экземпляра
class Singleton
{
public static Singleton Instance()
{
get
{
return instance;
}
}
private Singleton()
{
}
private static Singleton()
{
instance = new Singleton();
}
private static Singleton instance;
}
• Порождение подклассов
class Singleton
{
public static void Register(string name, Type type) ,…public static Singleton Instance
{
get
{
if(!instance)
{
instance = CreateInstanceByType(Lookup(Detect()));
}
return instance;
}
}
private static Type Lookup(name) ,…private static string Detect() ,…- //Определяет имя класса Singleton, которым должна быть сконфигурирована система
private static Singleton instance;
}
• Уничтожение синглетонов
– утечка ресурсов
– Висячая ссылка
Пример: Порядок уничтожения нескольких синглетонов
Display, Keyboard, Log
Варианты решения: феникс, синглетон с заданной
продолжительностью жизни
• Феникс
interface ISingleton
{
void DoSometing();
}
class Singleton: ISingleton
{
public static ISingleton Instance
{
get
{
if(!instance)
{
instance = new Singleton();
}
return new SingletonPhenix();
}
}
}

class SingletonPhenix: ISingleton
{
public virtual DoSomething()
{
Singleton.Instance.DoSomething();
}
internal SingletonPhenix();
}

• Не хранить ссылки на
синглетон, везде
использовать вызов
свойства Instance
• Состояние разрушенного
объекта теряется
• Синглетон с заданной продолжительностью жизни
– Каждому синглетону ставится в соответствие целое число –
“продолжительность жизни”.
– Список всех синглетонов упорядочивается по продолжительности
жизни.
– Синглетоны уничтожаются в порядке увеличения
продолжительности жизни.
– Сам список – это тоже синглетон с наибольшей
продолжительностью жизни.
– Необходим интерфейс по регистрации синглетонов в общем
списке.
• Многопоточная среда
private static object locker;
public static Singleton Instance
{
lock(locker)
{
if(!instance)
{
instance = new Singleton();
}
return instance;
}
}

– Неприемлемо из-за больших накладных расходов на
блокировку
Пример 04.006.01-2011
Известные применения
• AppDomain
public static AppDomain CurrentDomain { get; }
• Application
public static Application Current { get; }
Родственные паттерны
• Абстрактная фабрика часто реализуется в виде Синглетона
Адаптер
• Категория: структурный паттерн
• Назначение: преобразует интерфейс одного класса в
интерфейс другого, который ожидают клиенты. Адаптер
обеспечивает совместную работу классов с
несовместимыми интерфейсами, которая без него была
бы невозможна.
• Синоним: Wrapper(Обертка)
Мотивация
• Есть готовый класс, который предоставляет нужную
функциональность.
• Но интерфейс класса не позволяет использовать его
непосредственно без изменения.
• Если будем переписывать класс, то нет гарантии, что в будущем
не возникнет ситуации, когда этот класс не придется
приспосабливать под еще один вариант использования.
• Согласно открыто-замкнутому принципу, существующий класс
модифицировать нельзя.
• Выход: создать класс с нужным интерфейсом, но который
реализует его через вызов методов существующего класса.
Аналог адаптеров в жизни: адаптеры(переходники) для розеток.
Применимость:
• Надо использовать существующий класс, но его интерфейс не
соответствует текущим потребностям
• Надо создать повторно используемый класс, который должен
взаимодействовать с заранее неизвестными и не связанными с
ним классами, имеющими несовместимый между собой
интерфейс
(Программа Copy, УК 01.001)
• (Адаптер объектов) Нужно использовать иерархию классов.
Согласно принципу подстановки Лисков адаптер базового
класса должен быть написан без знания того, экземпляр какого
именно класса он адаптирует. Следовательно, адаптер базового
класса можно применить ко всей иерархии классов.
Структура (адаптер классов)
Структура (адаптер объектов)
Результаты (адаптер объектов)
• (+) Один адаптер может применяться ко многим классам
(базовый класс и его подклассы). Адаптер добавляет
новую функциональность сразу всем адаптируемым
классам.
• (-) Для замещения операций класса Adaptee надо создать
класс производный от Adaptee и сделать так, чтобы
адаптер ссылался на этот новый класс
Реализация
• Объем работы по адаптации
• Сменные адаптеры
Применяется для уменьшения количества предположений о классах, с
которыми взаимодействует данный класс. В такой класс должна быть
встроена возможность по адаптации интерфейса.
Пример: Универсальная форма по вводу объявлений
– Абстрактные операции (лучше не использовать так, как противоречит принципу
обращения зависимостей)
Пример: специализация формы для каждого вида объявлений
– Использование объектов-уполномоченных (улучшение предыдущего подхода,
соответствует принципу обращения зависимостей)
Пример: Форма использует специальный интерфейс по добавлению полей в каждый вид
объявления
interface IAd
{
void Add(Field field);
}

– Параметризованные адаптеры
Пример: биндинг данных на форму, шаблон объявления

•

Двусторонние адаптеры
Пример 04.007.01-2011
Известные применения
• Adapter Represents a base class for the adapter developed using
the WCF LOB Adapter SDK.
Namespace: Microsoft.ServiceModel.Channels.Common
Assembly: microsoft.servicemodel.channels.dll
• Adapter Используется для адаптации логики отдельных
элементов.
Namespace: Microsoft.Windows.Design.Interaction
Assembly: Microsoft.Windows.Design.Extensibility.dll
• cHTML Adapter Set The cHTML adapter set renders ASP.NET mobile
Web pages on clients that are capable of rendering HTML 3.2 but
do not support client scripting. This adapter set includes special
support for cHTML, the markup language used on i-mode phones.
Родственные паттерны
• Мост реализуется аналогично адаптеру, но у моста другое
назначение.
• Декоратор очень похож на адаптер, но используется подругому.
Компоновщик
• Категория: паттерн, структурирующий объекты
• Назначение: Компонует объекты в древовидные
структуры для представления иерархий “part of”.
Позволяет клиентам единообразно трактовать
индивидуальные и составные объекты.
Мотивация
• Объекты в программе образуют иерархии “part of”.
Например, объявление и поле объявления; поле, в свою
очередь может быть составным, например, площадь
жилой недвижимости.
• Какие иерархии являются “правильными” с точки зрения
ООП?
• По аналогии с принципом подстановки Лисков: надо
единообразно трактовать атомарные и составные
объекты.
• Значит атомарные и составные объекты должны иметь
общий интерфейс
Структура
Структура типового составного
объекта
Результаты
• Определяет иерархии классов, состоящие из примитивных
и составных объектов.
• Упрощает архитектуру клиента.
• Облегчает добавление новых видов компонентов.
Изменять клиента при добавлении новых компонентов не
нужно.
• Способствует созданию общего дизайна.
Трудно ограничить, чтобы составной компонент включал
только определенные виды компонентов.
Реализация
•
•
•
•
•
•
•
•
•

Явные ссылки на родителей
Разделение компонентов (паттерн Приспособленец)
Максимизация интерфейса класса Component
Объявление операций для управления потомками (исключение
из принципа соответствия интерфейсов, УК 03.001)
Должен ли Component реализовывать список компонентов
Упорядочивание потомков (паттерн Итератор)
Кэширование для повышения производительности
Кто должен удалять компоненты
Какая структура данных лучше всего подходит для хранения
компонентов (паттерн Интерпретатор)
Пример кода (ПР 04.008.01-2011)
Известные прменения
• Control - класс (System.Windows.Controls, System.Web.UI,
System.Windows.Forms)
• XMLNode (System.XML)
Родственные паттерны
• Цепочка обязанностей использует паттерн Компоновщик
• Декоратор часто совместно используется с
компоновщиком
• Паттерн приспособленец позволяет разделять
компоненты
• Итератор может использоваться для обхода составных
объектов
• Посетитель локализует операции и поведение, которое
пришлось бы распределять между классами Composite и
Leaf.
Фасад
• Категория: паттерн, структурирующий объекты
• Назначение: Предоставляет унифицированный интерфейс
вместо набора интерфейсов некоторой подсистемы.
Фасад определяет интерфейс более высокого уровня,
который упрощает использование подсистемы.
Мотивация
• Есть сторонний компонент, который хотелось бы
использовать в приложении
• Приложение не должно зависеть от используемого
компонента
• Согласно принципу обращения зависимостей необходимо
выделить интерфейсы, которые будет использовать наше
приложение и предоставить реализацию этих
интерфейсов через сторонний компонент.
• Полученный набор классов и будет фасадом.
Применимость
• Необходимо предоставить интерфейс к сложной
подсистеме. Фасад предлагает некоторый вид системы,
устраивающий большинство клиентов. И лишь те объекты,
которым необходимы более широкие настройки, могут
обратиться напрямую к тому, что находится за фасадом.
• Между клиентами и классами реализации существует
много зависимостей. Фасад позволяет отделить
подсистему как от клиентов, так и от других подсистем.
• Необходимо разложить систему на отдельные слои. Фасад
будет представлять точку входа на каждый отдельный
уровень подсистемы.
Структура
Результаты
• Изолирует клиентов от компонентов под системы
• Позволяет ослабить связность между под системой и ее
клиентами.
• Фасад не препятствует приложениям обращаться
напрямую к классам подсистемы, если это необходимо.
Реализация
• Уменьшение степени связности.
• Закрытые и открытые классы подсистем.
Пример кода (ПР 04.009.01-2011)
Известные применения
• Платформа .Net
– WinForms, WPF
– ADO .Net
– WCF, Remoting
Родственные паттерны
• Абстрактная фабрика (для создания фасада, как
альтернатива)
• Посредник
• Адаптер
• Декоратор
• Синглетон
• Мост
• Итератор
Наблюдатель
• Категория: паттерн поведения объектов
• Назначение: Определяет зависимость типа “один ко
многим” между объектами таким образом, что при
изменении состояния одного объекта все зависящие от
него оповещаются об этом и автоматически обновляются.
• Синоним: Dependends (Подчиненные), Publish-Subscribe
(издатель-подписчик).
Мотивация
• Объект класса Subject меняет свое состояние с течением
времени
• Есть несколько других объектов разных классов, которым
необходимо знать об этих изменениях.
• Зашивать в код Subject информирование этих объектов об
изменении состояния противоречит открыто-замкнутому
принципу – могут появиться новые.
• Описываем поведение, которое отвечает за
информирование объектов в отдельный интерфейс
IObserver.
• Вызываем методы IObserver из класса Subject.
Применимость
• У абстракции есть два аспекта, из которых один зависит от
другого. Наблюдатель позволяет инкапсулировать эти
аспекты в разные объекты и изменять и повторно
использовать независимо друг от друга.
Пример: объявление, квоты, проверка черных списков
• При изменении одного объекта необходимо изменить
другие объекты, а их общее количество неизвестно.
• Один объект должен оповещать других, не делаю
предположений об уведомляемых объектах.
Структура
Результаты
• Абстрактная связность наблюдаемого объекта и
наблюдателя
Побочные эффекты
• Поддержка широковещательных коммуникаций
• Неожиданные обновления
Реализация
• Отображение субъектов на наблюдателей
Пример: event предоставляет возможность переопределять
механизм подписки с помощью методов Add и Remove
Пример: Ex 04.011.01-2011
• Наблюдение более чем за одним объектом
Пример: Обработчики событий содержат объект-источник события
• Кто инициирует обновление
Push и pull-модели получения информации
• Как избежать зависимости протокола обновления от
наблюдателя:
Push и pull-модели получения информации
• Висячие ссылки на удаленные наблюдаемые объекты
• Гарантия непротиворечивости состояния перед отправкой
уведомления
Легко нарушить, если вызывать унаследованные методы базового
класса из переопределенных методов наследника.
class Ad
{
public virtual void Load()
{
…
Notify();
}
}
class AutoAd: Ad
{
public override void Load()
{
base.Load();
this.model = storage*“model”+;
this.marka = storage*“marka”+;
}
}
• Подписка только на интересующие модификации
Пример: событийная модель позволяет подписываться
только на интересующие события
• Комбинирование классов Subject и Observer
• Инкапсуляция сложной семантики обновления
Нужно:
– отношения зависимости между объектами становятся сложными,
– Необходимо выполнить серию однотипных обновлений,
выполнение обновления выполняется достаточно долго

Примеры:
1. Ведение логов.
2. Расчет квот.
• Синхронная и асинхронная обработка обновлений
GUI обрабатывается в одном потоке
• Интеграция приложений
Пример кода
• Ex 04.010.01-2011 (рекомендации Microsoft по
использованию событий)
• Ex 04.011.01-2011 (отображение субъекта на наблюдатели)
Идеи по проектам
• Медленно работает конвертор
– Делать проверки для группы объявлений

• Фотопроцессор
– Сообщение с заданием на конвертацию
Известные применения
• Обработка событий в любом GUI
• Механизм подписки через events и delegates платформы
.Net
• WPF
• Паттерны интеграции корпоративных приложений
Родственные паттерны
• Команда: обработчики событий
• Цепочка ответственности: маршрутизация событий
• Посредник: сложные случаи обновления данных
Команда
• Категория: паттерн поведения объектов
• Назначение: Инкапсулирует запрос в виде объекта,
позволяя задавать параметры запросов, ставить их в
очередь, протоколировать, делать отмену.
• Синоним: Action, Transaction.
Мотивация
• Есть класс, который знает когда нужно выполнить
действие, но не знает какое, и есть класс, который знает
какое действие выполнить, но не знает, когда
Например, текстовое поле
• Выделяем интерфейс Command, который описывает
поведение Выполнить действие
• Тогда класс, который знает когда нужно выполнить
действие, может вызывать любое действие не зная сути
этого действия.
Применимость
• Необходимо параметризовать объекты выполняемым
действием – альтернатива функциям обратного вызова
Пример:
– Алгоритм быстрой сортировки
– Обработчик событий формы

• Определять, ставить запросы в очередь, выполнять в
разное время (даже в другом адресном пространстве)
• Поддерживать отмену операций
• Поддерживать протоколирование изменений
• Структурировать систему на основе высокоуровневых
операций, построенных из примитивных.
Структура
Результаты
• Разрыв связи между объектом, вызывающим операцию и
объектом, знающим, как эту операцию выполнить
• Команда – полноценный объект, которым можно
манипулировать и расширять
Побочные эффекты
• Из простых команд можно собирать составные
• Добавлять новые команды легко
Реализация
• Степень смышлености команды
Две крайности:
– Вызов операций получателя
– Самостоятельное выполнение всех операций

• Поддержка повтора и отмены операций
Дополнительный метод Unexecute Выполняет действие
обратное к действию Execute
Например: символа ‘a’ в 5 строке 3 символ – удалить 3
символ в пятой строке
• Макрокоманды
Для реализации применяется паттерн компоновщик
Вопросы реализации:
– Видит ли следующая команда измененные значения out
параметров
– Если команды возвращают значение, то что будет возвращать
макрокоманда
– Если одна из команд генерирует исключение, то продолжать
выполнение остальных и, если нет, то следует ли выполнять откат
уже выполненных команд?

• Накопление ошибок в процессе отмены
Сохранять немного больше информации, чем это
необходимо для выполнения операции
Пример кода
Ex 04.012.01-2011
Известные применения
• delegate
• Action<T>
Родственные паттерны
• Компоновщик для создания макрокоманд
• Хранитель для запоминания информации необходимой
для отмены команды
• Прототип, если необходимо копировать команду,
например, для сохранения в истории
• Команда используется совместно с наблюдателем для
того, чтобы снизить зависимость наблюдаемого объекта от
деталей наблюдателя
• Команда используется совместно с цепочкой
ответственности, чтобы выбрать наиболее подходящую
для выполнения команду
Приспособленец
• Категория: структурный паттерн
• Назначение: Оптимизация использования ресурсов в
случае множества мелких объектов
Мотивация
• Слишком большие расходы на хранение объектов
Часто является причиной отказа от ООП
• Уменьшить количество объектов до необходимого уровня,
путем разделения одного объекта между нескольким
сущностями предметной области
• Сущности чем-то отличаются между собой
• Различие в сущностях выражается в разных значениях
данных
• Надо придумать способ вычисления данной информации
по набору данных, меньшему по объему, чем прямое
хранение данных
Применимость
• большое число объектов, из-за этого накладные расходы
на хранение высоки
• Большую часть состояния объекта можно вынести вовне
• Многие группы объектов можно заменить небольшим
количеством разделяемых объектов
• Приложение не зависит от идентичности объекта
Примеры:
Автоматы, схемы электрической цепи (любые диаграммы),
векторная графика, текстовый редактор
Структура
Результаты
• Уменьшение объема памяти
Побочные эффекты
• Сокращение числа экземпляров
• Вычисление, а не хранение внешнего состояния
Реализация
• Управление разделяемыми объектами
• Вынесение внешнего состояния
Пример кода
Ex 04.013.01-2011
Известные применения
?
Родственные паттерны
• Компоновщик. Ациклический направленный граф с
разделяемыми листовыми вершинами.
• Состояние и стратегия часто реализуются через
Приспособленца
• Хранитель для сохранения внешнего состояния
Приспособленца
Хранитель
• Категория: паттерн поведения объектов
• Назначение: Не нарушая инкапсуляции, выносит за
пределы объекта его внутренне состояние, так, чтобы в
нем, позднее, можно было восстановить объект.
• Синоним: Token.
Мотивация
• Есть объект Хозяин, состояние которого надо хранить дольше,
чем время жизни процесса, его создавшего
• При сохранении состояния объекта необходимо иметь доступ
ко внутренним данным
• Предоставление доступа ко внутренним данным ведет к
нарушению инкапсуляции
• Выход: создать класс Хранитель, который будет частью
реализации объекта Хозяина и который будет заключать в себе
внутренне состояние Хозяина.
• Чтобы не было нарушения инкапсуляции класс Хранитель
должен предоставлять два интерфейса – “открытый” для
хранилища, куда будет записываться состояние объекта и
“расширенный” – доступный только для Хозяина.
Применимость
• Необходимо сохранить мгновенный снимок объекта или
его части, чтобы потом можно было восстановить в нем
объект
• Прямой доступ к этому состоянию нарушает
инкапсуляцию и раскрывает детали реализации
Структура
Результаты
• Сохранение границ инкапсуляции
• Упрощение структуры хозяина
• Значительные издержки при использовании хранителей
• Скрытая плата за содержание хранителя
Побочные эффекты
• Определение “узкого” и “широкого” интерфейсов
Пример кода
Ex 04.014.01-2011
Известные применения
• ORM
• ?
Родственные паттерны
• Команда: Хранитель используется для хранения
внутреннего состояния команд
• Итератор: С помощью итератора осуществляется перебор
хранителей в Хранилище
• Приспособленец использует Хранителя для манипуляции
состояния, выносимого за пределы приспособленца
Шаблонный метод
• Категория: паттерн поведения объектов
• Назначение: Определяет основу алгоритма и позволяет
подклассам переопределять некоторые шаги алгоритма,
не изменяя его структуру в целом.
Мотивация
• Несколько функций концептуально похожи друг на друга,
но отличаются вызываемыми функциями, или есть
длинный метод.
• Выделяем набор блоков, в каждой из функций.
• Каждый из этих блоков оборачиваем вызовом операции.
• Полученные операции образуют набор примитивных
операций и функций-зацепок.
• Преобразованный метод реализует паттерн Шаблонный
метод.
Применимость
• Повторно использовать неизменные части алгоритма,
позволяя подклассам переопределять реализацию
изменяющегося поведения
• Для управления расширениями подклассов. Точки
расширения – функции-зацепки.
Результаты
• Шаблонные методы приводят к инвертированной
структуре кода (принцип обращения зависимостей)
• Шаблонные методы вызывают операции следующих
видов:
–
–
–
–
–

Конкретные операции (из ConcreteClass, либо из клиента)
Конкретные операции из AbstractClass
Примитивные операции
Фабричные методы
Операции-зацепки (операции, имеющие реализацию по
умолчанию, которые могут быть переопределены в подклассах)
Структура
Реализация
• Контроль доступа (видимость, абстрактные операции)
• Сокращение числа примитивных операций
• Соглашение об именах
Например, имена замещаемых операций начинаются с префикса Do
Пример кода
• Ex 04.015.01-2011
Известные применения
• XpathNavigator (System.XML.XPath)
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–
–

NameTable
Clone
NodeType
LocalName
Name
NamespaceURI
Prefix
BaseURI
IsEmptyElement
MoveToFirstAttribute
MoveToNextAttribute
MoveToFirstNamespace
MoveToNextNamespace
MoveToNext
MoveToPrevious
MoveToFirstChild
MoveToParent
MoveTo
MoveToId
IsSamePosition
Value

–
–
–
–

AppendChild
CreateAttribute
CreateAttributes
CreateNavigator
Родственные паттерны
• Фабричные методы часто вызываются в шаблонах
• Стратегии применяются для делегирования модификации
алгоритма в целом
Стратегия
• Категория: паттерн поведения объектов
• Назначение: Определяет семейство алгоритмов,
инкапсулирует каждый из них и делает их
взаимозаменяемыми.
• Синоним: Policy (Политика).
Мотивация
• Есть несколько операторов switch или цепочек if-else-if
• Такие конструкции противоречат Открыто-замкнутому
принципу, так как делают программу нерасширяемой
• Заменим каждый switch или цепочку if-else-if на
полиморфную операцию
• Необходимо гарантировать, что определенные
реализации виртуальных функций используются
совместно
• Перенесем все выделенные операции в один интерфейс.
• Те реализации функций, которые должны использоваться
совместно реализуем в одном классе-наследнике от
выделенного интерфейса.
Применимость
• Имеется много родственных классов, отличающихся
только поведением
• Необходимо иметь несколько вариантов алгоритма
• В алгоритме содержатся данные, о которых клиент не
должен знать
• В классе определено много поведений, которые
представлены разветвленными условными операторами
Структура
Результаты
• Семейства родственных алгоритмов
• Альтернатива порождению подклассов
• С помощью стратегий можно избавиться от условных
операторов
• Выбор реализации
Побочные эффекты
• Клиенты должны знать о различных стратегиях
• Увеличение числа объектов
• Обмен информацией между стратегией и контекстом
Реализация
• Обмен данными между стратегией и контекстом
• Стратегии как параметры generic-типов
Пример кода
• Ex 04.016.01-2011
• Ex 04.017.01-2011
Известные применения
•
•
•
•

XMLSerializationReader, XMLSerializationWriter
IComparable
IDisposable
IConvertible
Родственные паттерны
• Объекты-стратегии удобно реализовывать в виде
приспособленцев
• Стратегии используются для параметризации шаблонного
метода
Посредник
• Категория: паттерн поведения объектов
• Назначение: Определяет объект, инкапсулирующий
способ взаимодействия множества объектов. Посредник
обеспечивает слабую связность, избавляя компоненты от
необходимости явно ссылаться друг на друга.
• Синоним: Controller (Контроллер).
Мотивация
• В системе много классов, которые сильно связаны между
собой (каждый с каждым).
• Получаем нарушение открыто-замкнутого принципа.
• Идея: прием как в случае отношения “многие-ко-многим”
– создать объект, с которым будут взаимодействовать все
остальные.
• Тогда все остальные объекты можно использовать
повторно.
Применимость
• Имеются объекты, связи между которыми сложны и
нечетко определены, взаимозависимости трудны для
понимания.
• Нельзя повторно использовать объект, поскольку он
обменивается информацией с другими объектами.
• Поведение, распределенное между несколькими
классами, должно поддаваться настройке без порождения
подклассов.
Структура
Результаты
• Устраняет связность между коллегами
• Упрощает протоколы взаимодействия объектов
• Абстрагирует способ кооперирования объектов
Побочный эффект
• Централизует управление
• Снижает число порождаемых подклассов
Пример кода
• Ex 04.018.01-2011
Известные применения
• MVC (ASP .Net MVC Framework, BL)
• Форма приложения часто является посредником для
своих дочерних элементов
Родственные паттерны
• Фасад часто реализуется как совокупность посредников.
• Посредник может быть реализован в виде наблюдателя по
отношению к коллеге-инициатору взаимодействия и в
виде наблюдаемого объекта по отношению к коллегеконечной точке взаимодействия.
• Коллеги могут быть реализованы в виде приспособленцев,
в этом случае посредник занимается инициализацией
состояния приспособленцев, хранимой вовне.
Декоратор
• Категория: паттерн структурирующий объекты
• Назначение: Динамически добавляет объекту новые
обязанности. Альтернатива порождению подклассов.
• Синоним: Wrapper (Обертка).
Мотивация
•
•
•
•
•
•
•

Есть иерархия классов, ко всем объектам которой необходимо добавить
дополнительное поведение на время выполнения одной операции.
Модифицировать базовый класс нельзя, так как нарушим открытозамкнутый принцип.
Значит надо создать новый класс.
Чтобы не нарушить принцип подстановки Лисков, надо чтобы новый класс
мог быть использован всеми клиентами без явной ссылки на этот класс.
Это можно сделать, только если класс реализует тот же самый интерфейс,
что и базовый класс иерархии.
Чтобы не дублировать поведение существующих классов, новый должен
реализовывать только новое поведение самостоятельно, а остальное –
делегировать уже существующим классам.
Это возможно, если новый класс будет хранить ссылку на декорируемый
объект и делегировать ему выполнение всех операций.
Применимость
• Динамическое, прозрачное для клиентов добавление
обязанностей
• Реализация обязанностей, которая может быть снята с
клиента.
• Замена расширения с помощью подклассов.
Структура
Результаты
• Большая гибкость, чем у статического наследования.
• Уменьшает количество перегружаемых функций на
верхних уровнях иерархии классов.
Побочные эффекты:
• Декоратор и его компонент не идентичны.
• Множество мелких объектов.
Реализация
•
•
•
•

Соответствие интерфейсов
Отсутствие абстрактного класса декоратор
Облегченные классы Component
Изменение внешнего поведения, а не реализации
Пример кода
Известные применения
• System.Reflection.TypeDelegator
protected Type typeImpl
• ReadOnly коллекции
public static IList ArrayList.ReadOnly( IList list );
• Исправление ошибки в библиотеке работы с MySQL на Qt3
Родственные паттерны
• Адаптер vs. Декоратор
• Декоратор можно реализовывать как
– Singleton
– Flyweight
Итератор
• Категория: паттерн поведения объектов
• Назначение: Предоставляет доступ ко всем элементам
составного объекта, не раскрывая его внутреннего
состояния.
• Синоним: Cursor.
Мотивация
• Есть алгоритм, который перебирает элементы некоторого
составного объекта
• Способ перебора элементов – это деталь реализации
составного объекта
• Если алгоритм будет зависеть от деталей реализации
перебираемого им составного объекта, то его придется
переписывать каждый раз, когда меняется реализация этого
объекта.
• Согласно принципу обращения зависимостей мы должны
определить интерфейс перебора составного объекта и через
него реализовать алгоритм, а составному объекту дать
возможность реализовать этот интерфейс.
• Выделенный интерфейс и будет иетратором.
Применимость
• Доступ к содержимому составных объектов, не раскрывая
деталей реализации.
• Несколько активных обходов одного составного объекта
• Единообразный интерфейс обхода для разных составных
объектов.
Структура
Результаты
• Различные виды обходов составного объекта
• Упрощение интерфейса составного объекта
• Несколько активных обходов одного и того же составного
объекта
Побочный эффект
• Изменение в структуре составного объекта может
повлиять на активные обходы
Реализация
• С++ и Java-стиль итераторов
– С++-стиль

ContainerType C; // Любой стандартный тип контейнера, например std::list<sometype>
//for (ContainerType::iterator it = C.begin(),end = C.end(); it != end; ++it) //(если вам нужно изменять элементы)
for (ContainerType::const_iterator it = C.begin(),end = C.end(); it != end; ++it)
{
std::cout << *it << std::endl;
}

ContainerType<ItemType> C; // Любой стандартный тип контейнера элементов ItemType
void ProcessItem( const ItemType& I ) // Функция, обрабатывающая каждый элемент коллекции
{
std::cout << I << std::endl;
}
std::for_each( C.begin(), C.end(), ProcessItem ); // Цикл просмотра
– Java-стиль

// 'явная' версия
IEnumerator<MyType> iter = list.GetEnumerator();
while (iter.MoveNext())
{
Console.WriteLine(iter.Current);
}
// 'неявная' версия
foreach (MyType value in list)
{
Console.WriteLine(value);
}
• Внешние и внутренние
– Внешние рассмотрены выше
– Внутренние
AdsGrid grid = new AdsGrid();
grid.MoveToFirst();
while(grid.IsLast())
{
doSomething(grid.Current());
}

Закладки – обеспечение нескольких активных просмотров
одновременно
AdsGrid grid = new AdsGrid();
grid.MoveToFirst();
while(!grid.IsLast())
{
Log(grid);
doSomething(grid.Current());
grid.MoveToNext();
}
void Log(AdsGrid grid)
{
grid.MoveToFirst();
while (!grid.IsLast())
{
LogOneRecord(grid.Current());
grid.MoveToNext();
}
}

Решение
class Bookmark: IDisposable
{
private GridCursor old;
private AdsGrid grid;
public Bookmark(AdsGrid grid)
{
old = grid.Current();
this.grid = grid;
}
public void Dispose()
{
grid.SetCursor(old);
}
}
AdsGrid grid = new AdsGrid();
using (Bookmark bookmark = new Bookmark(grid))
{
grid.MoveToFirst();
while(!grid.IsLast())
{
Log(grid);
doSomething(grid.Current());
grid.MoveToNext();
}
}
void Log(AdsGrid grid)
{
using (Bookmark bookmark = new Bookmark(grid))
{
grid.MoveToFirst();
while (!grid.IsLast())
{
LogOneRecord(grid.Current());
grid.MoveToNext();
}
}
}
• Набор методов итератора
– Для чтения
public T Current
{
get;
}

– Для записи
public T Current
{
get;
}

– Односторонний
public bool MoveNext();

– Двусторонний
public bool MovePrevious();

– С произвольным доступом
public T this[int index]
{
get;
}
•
•
•
•

Полиморфные итераторы
Устойчивость итератора к изменениям контейнера
Доступ ко внутреннему представлению контейнера
Итераторы и составные объекты
– Несколько уровней вложенности
– Несколько способов обхода

• Пустые итераторы
Могут применяться вместе паттерном компоновщик для листовых
элементов древовидных структур
Пример кода
Известные применения
• IEnumerator<T> (System.Collections.Generic)
• DbDataReader (System.Data.Common)
• Stream (System.IO)
Родственные паттерны
• Часто используются совместно с компоновщиком для
составных объектов
• Фабричный метод для создания полиморфных итераторов
(GetEnumerator())
• Хранитель для сохранения состояния итератора (Закладка
для внутренних итераторов)
Состояние
• Категория: паттерн поведения объектов.
• Назначение: Изменение поведения в зависимости от
внутреннего состояния объекта.
Мотивация
• Объект может пребывать в нескольких состояниях
(установка соединения, запущен, приостановлен,
запускается, остановлен и т.д.)
• От этих состояний зависит поведение объекта, причем
поведение может очень сильно отличаться
• У объекта могут появляться новые состояния, либо
меняться переходы между существующими
• Локализуем поведение каждого из состояний внутри
отдельного класса.
Применимость
• Поведение объекта зависит от состояния, которое должно
меняться динамически
• В коде много последовательностей if-else-if, выбор веток
которых зависит от состояния объекта
Структура
Результаты
• Локализует, зависящее от состояние поведение в
отдельных классах, разбивая его тем самым на части,
каждая из которых соответствует одному состоянию.
• Явные переходы между состояниями
Побочные эффекты
• Объекты состояния можно разделять (Flyweight)
Реализация
•
•
•
•

Кто должен определять переход между состояниями
Таблица переходов между состояниями
Создание и уничтожение объектов состояния
Использование динамического наследования
Пример кода
Известные применения
• WWF
•
•
•
•

Windows сервисы
Потоки
Сокеты
Соединения
Родственные паттерны
• Приспособленец для разделения объектов состояния
• Состояние часто реализуется в виде одиночки
• Состояние может реализовываться в виде команды или
последовательности команд
Цепочка ответственности
• Категория: паттерн поведения объектов.
• Назначение: Позволяет избежать привязки отправителя
запроса к его получателю, давая шанс обработать его
нескольким объектам.
Мотивация
• Есть запрос, который должен обработать один из
множества, возможно динамического, объектов
• Поскольку количество объектов нам неизвестно, то
должна быть динамическая структура данных,
позволяющая хранить в себе все это множество
• Объекты имеют разную природу, следовательно, чтобы их
унифицировать для обработки сообщений, надо, чтобы
они реализовывали один и тот же интерфейс.
• Чтобы клиент не пришлось перебирать все множество
объектов-получателей запроса, нужно предоставить им
самим принимать решение – кто будет обрабатывать
запрос
Применимость
• Есть более одного объекта, способного обработать запрос,
причем обработчик заранее неизвестен
• Необходимо отправить запрос одному из нескольких
объектов, не указывая, какому именно
• Набор объектов способных обработать запрос, должен
задаваться динамически
Структура
Результаты
• ослабление связанности
• дополнительная гибкость при распределении
обязанностей
“-”
• получение сообщения не гарантировано
• Замедление работы приложения, в случае, если цепочки
будут слишком длинными, а сообщений много
(Qt 4.*)
Реализация
• Цепочка приемников
– На основе существующих связей (например, ссылки,
используемые Компоновщиком)
– Организация новых связей

• Реализация обработчика по умолчанию
• Представление запросов
– Один запрос – функция обработчик
– Много запросов – запрос-объект

• Автоматическое перенаправление запросов (PHP,
Javascript)
Пример кода
• Ex 04.021.01-2011
Известные применения
• GUI, Web-интерфейс
• WWF, WinForms
• ASP .Net MVC, Ruby on Rails, Zend Framework
• Фильтры сообщений

• System.Collections.Concurrent.ConcurrentQueue<T>
• Message Queue
Родственные паттерны
• Часто применяется совместно с паттерном компоновщик
• Обработка запросов осуществляется паттерном команда
Заместитель
• Категория: паттерн структурирующий объекты.
• Назначение: Является суррогатом другого объекта и
контролирует доступ к нему.
• Синоним: Surrogate
Мотивация
• Есть уже готовый класс, понадобилась возможность
разграничения доступа. Часть методов данного класса
может быть недоступно, в зависимости от набора прав.
• Разбивать класс на несколько в соответствии с правами
доступа – нарушение открыто-замкнутого принципа,
кроме того, права могут меняться.
• Создать класс с тем же интерфейсом, что и исходный,
только при вызове каждого метода будет проверяться
права доступа, и в случае, если прав достаточно –
вызывать метод исходного объекта.
Применимость
• “Посол”. Локальный представитель вместо объекта
находящегося в другом адресном пространстве. (WCF, .Net
Remoting)
• “Виртуальный заместитель”. Создает “тяжелые” объекты по
требованию. (Например, картинка, отложенные вычисления,
ленивая инициализация)
• “Защищающий” заместитель. Контролирует доступ к исходному
объекту. (Разграничение прав доступа).
• “Умная ссылка”
– Подсчет числа ссылок на реальный объект. Например, копирование
при записи.
– Загрузка объекта в память при первом обращении к нему
– Проверка и установка блокировки на реальный объект при первом
обращении к нему
Структура
Результаты
Зависят от типа Прокси
• Посол скрывает факт удаленности объекта
• Виртуальные заместители выполняют оптимизацию
• Защищающий заместитель и умная ссылка решают
дополнительные задачи при доступе к объекту
Реализация
• Заместителю не всегда должен быть известен тип
реального объекта
• Как обращаться к еще не инстанцированному объекту?
Пример кода
• Ex 04.022.01-2011
• Ex 04.023.01-2011
Известные применения
• Ссылка на объект в .Net
• WCF, .Net Remoting
Родственные паттерны
• Адаптер vs. Заместитель
• Декоратор vs. Заместитель
Посетитель
• Категория: паттерн поведения объектов.
• Назначение: Описывает операцию, выполняемую
объектом некоторой структуры.
Мотивация
• Есть некоторый составной объект, процедура обхода которого
достаточно сложна
• Есть несколько операций по данному объекту, которые
используют данную процедуру обхода. Необходимо повторно
использовать процедуру обхода для выполнения всех операций
• Надо отделить саму процедуру обхода от операций, которые
выполняются во время обхода, выделив их в отдельный
интерфейс.
• Каждая операция, как правило применяется как какого-нибудь
элементу составного объекта, поэтому добавим в интерфейс по
одному методу на каждый элемент, который мы достигаем при
обходе.
• Раскладываем каждую операцию по методам интерфейса.
Применимость
• Объект включает в себя объекты многих классов, а
выполняемая операция должна зависеть от классов этих
объектов.
• Над объектами, входящими в состав сложный структуры,
надо выполнять различные операции и не хочется
добавлять эти операции в классы данных объектов –
иначе нарушим принцип соответствия интерфейсов.
• Классы объектов структуры меняются редко, а операции
над объектами добавляются часто.
Структура
Результат
• Упрощает добавление новых операций
• Объединяет родственные операции и отсекает те, которые
не имеют никакого отношения
• Посещение различных иерархий классов
• Аккумулирование состояния
“-”
• Добавление новых классов затруднено
• Нарушение инкапсуляции
Реализация
• Двойная диспетчеризация
• Какой участник несет ответственность за обход структуры
Пример кода
• Ex 04.024.01-2011
Известные применения
• XML сериализация
public class MyClass
{
public MyObject MyObjectProperty;
}
public class MyObject
{
public string ObjectName;
}
<MyClass>
<MyObjectProperty>
<ObjectName>My String</ObjectName>
</MyObjectProperty>
</MyClass>

• XPathNavigator (System.XML.Xpath)
XPathDocument document = new XPathDocument("books.xml");
XPathNavigator navigator = document.CreateNavigator();
XPathExpression query = navigator.Compile("/bookstore/book");
XPathNodeIterator nodes = navigator.Select(query);
XPathNavigator nodesNavigator = nodes.Current;
XPathNodeIterator nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Text, false);
while (nodesText.MoveNext())
{
Console.WriteLine(nodesText.Current.Value);
}
Родственные паттерны
• Компоновщик
• Интерпретатор
Паттерн Мост
• Категория: паттерн структурирующий объекты.
• Назначение: Отделить абстракцию от реализации, так
чтобы ее можно менять независимо.
• Описание: HandleBody (ОписательТело)
Мотивация
• В зависимости от внешних факторов у класса может быть
разная реализация
• Разницу в реализации описывать if-else-if нельзя, так
нарушит отрыто-замкнутый принцип
• Надо каждую из реализаций представить в виде
отдельного класса Implementor
• Для пользователя выбор реализации должен быть
прозрачен – значит надо скрыть факт различия
реализаций за специальным классом Handle
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011
ук 03.003.01 2011

More Related Content

What's hot

C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.Igor Shkulipa
 
Ввведение в java
Ввведение в javaВвведение в java
Ввведение в javaUnguryan Vitaliy
 
Александр Ярулин - Автоматизация тестирования с xUnit
Александр Ярулин - Автоматизация тестирования с xUnitАлександр Ярулин - Автоматизация тестирования с xUnit
Александр Ярулин - Автоматизация тестирования с xUnitYandex
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.Igor Shkulipa
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.Igor Shkulipa
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.Igor Shkulipa
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Javametaform
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.Igor Shkulipa
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.Igor Shkulipa
 
Testing RIA with Selenium
Testing RIA with SeleniumTesting RIA with Selenium
Testing RIA with SeleniumSergey Shvets
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Javametaform
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.Igor Shkulipa
 
Сетевое взаимодействие
Сетевое взаимодействиеСетевое взаимодействие
Сетевое взаимодействиеUnguryan Vitaliy
 

What's hot (15)

C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.C++ STL & Qt. Занятие 01.
C++ STL & Qt. Занятие 01.
 
Step 1
Step 1Step 1
Step 1
 
Ввведение в java
Ввведение в javaВвведение в java
Ввведение в java
 
Александр Ярулин - Автоматизация тестирования с xUnit
Александр Ярулин - Автоматизация тестирования с xUnitАлександр Ярулин - Автоматизация тестирования с xUnit
Александр Ярулин - Автоматизация тестирования с xUnit
 
C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.C++ STL & Qt. Занятие 11.
C++ STL & Qt. Занятие 11.
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.C++ STL & Qt. Занятие 07.
C++ STL & Qt. Занятие 07.
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Java
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.
 
Testing RIA with Selenium
Testing RIA with SeleniumTesting RIA with Selenium
Testing RIA with Selenium
 
Классы и объекты в Java
Классы и объекты в JavaКлассы и объекты в Java
Классы и объекты в Java
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
 
Сетевое взаимодействие
Сетевое взаимодействиеСетевое взаимодействие
Сетевое взаимодействие
 

Viewers also liked

Antipatterns in software (ru)
Antipatterns in software (ru)Antipatterns in software (ru)
Antipatterns in software (ru)Borys Lebeda
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеSergey Nemchinsky
 
Шаблоны проектирования баз данных — Введение
Шаблоны проектирования баз данных — ВведениеШаблоны проектирования баз данных — Введение
Шаблоны проектирования баз данных — ВведениеDenis Beskov
 
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитика
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитикаШаблонизируй это. Как паттерны требований облегчают жизнь аналитика
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитикаSQALab
 

Viewers also liked (6)

Antipatterns in software (ru)
Antipatterns in software (ru)Antipatterns in software (ru)
Antipatterns in software (ru)
 
Шаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. ВведниеШаблоны разработки ПО. Часть 1. Введние
Шаблоны разработки ПО. Часть 1. Введние
 
Шаблоны проектирования баз данных — Введение
Шаблоны проектирования баз данных — ВведениеШаблоны проектирования баз данных — Введение
Шаблоны проектирования баз данных — Введение
 
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитика
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитикаШаблонизируй это. Как паттерны требований облегчают жизнь аналитика
Шаблонизируй это. Как паттерны требований облегчают жизнь аналитика
 
Git
GitGit
Git
 
Gof design patterns
Gof design patternsGof design patterns
Gof design patterns
 

Similar to ук 03.003.01 2011

Шаблоны проектирования в Magento
Шаблоны проектирования в MagentoШаблоны проектирования в Magento
Шаблоны проектирования в MagentoPavel Usachev
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
ASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCGetDev.NET
 
C# Desktop. Занятие 15.
C# Desktop. Занятие 15.C# Desktop. Занятие 15.
C# Desktop. Занятие 15.Igor Shkulipa
 
PostSharp - Threading Model Library
PostSharp - Threading Model LibraryPostSharp - Threading Model Library
PostSharp - Threading Model LibraryAndrey Gordienkov
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)Alexander Gornik
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftAnton Loginov
 
Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansmetaform
 
Dependency injection
Dependency injectionDependency injection
Dependency injectionGetDev.NET
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4Technopark
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsCiklum
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.Igor Shkulipa
 
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)Pavel Tsukanov
 
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ыHappyDev
 
Платформа для автоматического тестирования Erlang проектов на примере UserGat...
Платформа для автоматического тестирования Erlang проектов на примере UserGat...Платформа для автоматического тестирования Erlang проектов на примере UserGat...
Платформа для автоматического тестирования Erlang проектов на примере UserGat...DevDay
 

Similar to ук 03.003.01 2011 (20)

Шаблоны проектирования в Magento
Шаблоны проектирования в MagentoШаблоны проектирования в Magento
Шаблоны проектирования в Magento
 
DESIGN PATTERNS? EASY!
DESIGN PATTERNS? EASY!DESIGN PATTERNS? EASY!
DESIGN PATTERNS? EASY!
 
паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
ASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVCASP.NET, MVC, ASP.NET MVC
ASP.NET, MVC, ASP.NET MVC
 
C# Desktop. Занятие 15.
C# Desktop. Занятие 15.C# Desktop. Занятие 15.
C# Desktop. Занятие 15.
 
PostSharp - Threading Model
PostSharp - Threading ModelPostSharp - Threading Model
PostSharp - Threading Model
 
PostSharp - Threading Model Library
PostSharp - Threading Model LibraryPostSharp - Threading Model Library
PostSharp - Threading Model Library
 
разработка бизнес приложений (7)
разработка бизнес приложений (7)разработка бизнес приложений (7)
разработка бизнес приложений (7)
 
Как пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на SwiftКак пройти собеседование и получить первую работу на Swift
Как пройти собеседование и получить первую работу на Swift
 
Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeans
 
Dependency injection
Dependency injectionDependency injection
Dependency injection
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4
 
Genome
GenomeGenome
Genome
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_Antipatterns
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.
 
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
ORM технологии в .NET (Nhibernate, Linq To SQL, Entity Framework)
 
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы
2014.12.06 02 Екатерина Боброва — Тестируем сложные backend-ы
 
Deep Dive in Magento DI
Deep Dive in Magento DIDeep Dive in Magento DI
Deep Dive in Magento DI
 
Платформа для автоматического тестирования Erlang проектов на примере UserGat...
Платформа для автоматического тестирования Erlang проектов на примере UserGat...Платформа для автоматического тестирования Erlang проектов на примере UserGat...
Платформа для автоматического тестирования Erlang проектов на примере UserGat...
 
Классы и объекты С#
Классы и объекты С#Классы и объекты С#
Классы и объекты С#
 

More from etyumentcev

Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016etyumentcev
 
Платформа SmartActors
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActorsetyumentcev
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?etyumentcev
 
Программирование глазами математика
Программирование глазами математикаПрограммирование глазами математика
Программирование глазами математикаetyumentcev
 
Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?etyumentcev
 
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...etyumentcev
 
матлогика для программистов
матлогика для программистовматлогика для программистов
матлогика для программистовetyumentcev
 
Математическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принциповМатематическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принциповetyumentcev
 
Как 7 студентов и филолог делали сложный проект
Как 7 студентов и филолог делали сложный проектКак 7 студентов и филолог делали сложный проект
Как 7 студентов и филолог делали сложный проектetyumentcev
 
разработка серверов и серверных приложений лекция №4
разработка серверов и серверных приложений лекция №4разработка серверов и серверных приложений лекция №4
разработка серверов и серверных приложений лекция №4etyumentcev
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3etyumentcev
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2etyumentcev
 
разработка серверов и серверных приложений лекция №1
разработка серверов и серверных приложений лекция №1разработка серверов и серверных приложений лекция №1
разработка серверов и серверных приложений лекция №1etyumentcev
 
высокопроизводиетльные системы без доп затрат
высокопроизводиетльные системы без доп затратвысокопроизводиетльные системы без доп затрат
высокопроизводиетльные системы без доп затратetyumentcev
 
зачем нужны системы управления проектами
зачем нужны системы управления проектамизачем нужны системы управления проектами
зачем нужны системы управления проектамиetyumentcev
 
введение в Sql
введение в Sqlвведение в Sql
введение в Sqletyumentcev
 
почему буксует тайм менеджмент
почему буксует тайм менеджментпочему буксует тайм менеджмент
почему буксует тайм менеджментetyumentcev
 
ук 03.011.01 2011
ук 03.011.01 2011ук 03.011.01 2011
ук 03.011.01 2011etyumentcev
 
ук 03.010.01 2011
ук 03.010.01 2011ук 03.010.01 2011
ук 03.010.01 2011etyumentcev
 
ук 03.009.01 2011
ук 03.009.01 2011ук 03.009.01 2011
ук 03.009.01 2011etyumentcev
 

More from etyumentcev (20)

Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
Об опыте применения jsonb в реальных проектах. Выступление на PgConf.Russia 2016
 
Платформа SmartActors
Платформа SmartActorsПлатформа SmartActors
Платформа SmartActors
 
Как жить в согласии с SOLID?
Как жить в согласии с SOLID?Как жить в согласии с SOLID?
Как жить в согласии с SOLID?
 
Программирование глазами математика
Программирование глазами математикаПрограммирование глазами математика
Программирование глазами математика
 
Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?Большие данные: как могут навредить и ка могут помочь?
Большие данные: как могут навредить и ка могут помочь?
 
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
математическое обоснование Solid принципов. Конференция dotnetconf (Челябинск...
 
матлогика для программистов
матлогика для программистовматлогика для программистов
матлогика для программистов
 
Математическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принциповМатематическое обоснование S.O.L.I.D принципов
Математическое обоснование S.O.L.I.D принципов
 
Как 7 студентов и филолог делали сложный проект
Как 7 студентов и филолог делали сложный проектКак 7 студентов и филолог делали сложный проект
Как 7 студентов и филолог делали сложный проект
 
разработка серверов и серверных приложений лекция №4
разработка серверов и серверных приложений лекция №4разработка серверов и серверных приложений лекция №4
разработка серверов и серверных приложений лекция №4
 
разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3разработка серверов и серверных приложений лекция №3
разработка серверов и серверных приложений лекция №3
 
разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2разработка серверов и серверных приложений лекция №2
разработка серверов и серверных приложений лекция №2
 
разработка серверов и серверных приложений лекция №1
разработка серверов и серверных приложений лекция №1разработка серверов и серверных приложений лекция №1
разработка серверов и серверных приложений лекция №1
 
высокопроизводиетльные системы без доп затрат
высокопроизводиетльные системы без доп затратвысокопроизводиетльные системы без доп затрат
высокопроизводиетльные системы без доп затрат
 
зачем нужны системы управления проектами
зачем нужны системы управления проектамизачем нужны системы управления проектами
зачем нужны системы управления проектами
 
введение в Sql
введение в Sqlвведение в Sql
введение в Sql
 
почему буксует тайм менеджмент
почему буксует тайм менеджментпочему буксует тайм менеджмент
почему буксует тайм менеджмент
 
ук 03.011.01 2011
ук 03.011.01 2011ук 03.011.01 2011
ук 03.011.01 2011
 
ук 03.010.01 2011
ук 03.010.01 2011ук 03.010.01 2011
ук 03.010.01 2011
 
ук 03.009.01 2011
ук 03.009.01 2011ук 03.009.01 2011
ук 03.009.01 2011
 

ук 03.003.01 2011

  • 1. УК 03.003.01-2011 Учебный курс. Обучение. Шаблоны ОО проектирования.
  • 2. Определение паттерна Паттерн проектирования – описание взаимодействия классов и объектов, адаптированных для решения задачи проектирования в конкретном контексте. • Кристофер Александр, 1977 для архитектуры • Паттерн – это не готовый к использованию набор классов, а лишь описание способа решения конкретной задачи. • Тригонометрическая подстановка для решения интеграла.
  • 3. Шаблон описания паттерна • • • • • • • • • • • • • Название и классификация паттерна Назначение Имя синоним Мотивация Применимость Структура Участники Отношения Результаты Реализация Пример кода Известные применения Родственные паттерны
  • 4. Абстрактная фабрика Категория: паттерн, порождающий объекты Назначение: Определяет интерфейс для создания набора взаимосвязанных или взаимозависимых объектов, так что клиент не знает о точных классов, используемых им объектов. Имя синоним: Kit (Инструментарий)
  • 5. Мотивация • Чтобы создать объект, надо явно указать имя класса, экземпляром которого будет объект. • Имя класса в тексте программы – потенциальный источник нарушения принципа подстановки Лисков и открыто-замкнутого принципа • Отказаться от упоминания имен класса в тексте программы невозможно, следовательно их использование должно быть максимально локализовано. • Идеальный вариант – имя класса упоминается лишь один раз во всем тексте программы, что избежать проблемы Copy-Paste
  • 6. • AbstractProductA CreateProductA() – метод инкапсулирует в себе создание экземпляра ProductA, нам доступен лишь интерфейс базового класса. Такой подход удовлетворяет принципу подстановки Лисков. • Как компоновать методы, создающие объекты? • Есть классы сильно сцепленные между собой, а есть – независимые. • Объединим методы, создающие сильно сцепленные объекты между собой в один класс (обобщенный принцип повторного использования, обобщенный принцип замкнутости)
  • 7. • Согласно принципу единственной ответственности каждый класс должен заниматься выполнением только одной операции. • Должен быть класс, единственной задачей которого является создание экземпляров сильно сцепленных между собой классов.
  • 8. Применимость: • необходимо обеспечить замкнутость относительно создания, компоновки и представления входящих в нее объектов (способ создания объекта скрыт за вызываемым методом); • Необходимо обеспечить ограничение – взаимосвязанные объекты должны использоваться вместе (реализации File, Directory); • Необходимо обеспечить конфигурирование одним из семейств классов (Работа через протокол Tcp, Udp); • Необходимо раскрыть только интерфейсы, реализация должна быть закрыта.
  • 10. Отношения • Во время выполнения создается единственный экземпляр класса ConcreteFactory, который создает определенные объекты-продукты. Для создания объектов-продуктов с другой реализацией клиент должен создать экземпляр другой конкретной фабрики. • Абстрактная фабрика делегирует создание объектов продуктов конкретной фабрике.
  • 11. Результат • Стратегическая замкнутость: – Клиентский код не зависит от конкретных классов продуктов. • Замкнутость не обеспечивается для: – Добавления новых видов продуктов. • Побочные эффекты: – Упрощает замену семейств продуктов; – Гарантия сочетаемости продуктов.
  • 12. Вопросы реализации • Фабрика как Singleton • Создание продукта: – Фабричный метод – Прототип • Расширяемые фабрики – Использование сборок – Распределенная фабрика (COM, процедура инициализация DLL)
  • 13. Пример 04.001.01-2011 • Интерфейсы выделены в отдельную фабрику • Главное приложение явно зависит только от интерфейсов • Выбор семейства классов можно настраивать из файла конфигурации. • Фабрикой закрываются только те классы, которые находятся за пределами текущего модуля. Если надо инстанцировать класс, который находится внутри данного модуля, то его имя можно использовать напрямую. Принцип эквивалентности единицы повторного использования и единицы релиза!!!
  • 14. Известные применения • System.DataCommon.DbProviderFactory (ADO .Net) static DbConnection CreateDbConnection( string providerName, string connectionString) { DbConnection connection = null; if (connectionString != null) { try { DbProviderFactory factory = DbProviderFactories.GetFactory(providerName); connection = factory.CreateConnection(); connection.ConnectionString = connectionString; } catch (Exception ex) { if (connection != null) { connection = null; } Console.WriteLine(ex.Message); } } return connection; }
  • 15. Методы DbProviderFactory • • • • • • • • CreateCommand Возвращает новый экземпляра класса поставщика, реализующий класс DbCommand. CreateCommandBuilder Возвращает новый экземпляра класса поставщика, реализующий класс DbCommandBuilder. CreateConnection Возвращает новый экземпляра класса поставщика, реализующий класс DbConnection. CreateConnectionStringBuilder Возвращает новый экземпляра класса поставщика, реализующий класс DbConnectionStringBuilder. CreateDataAdapter Возвращает новый экземпляра класса поставщика, реализующий класс DbDataAdapter. CreateDataSourceEnumerator Возвращает новый экземпляра класса поставщика, реализующий класс DbDataSourceEnumerator. CreateParameter Возвращает новый экземпляра класса поставщика, реализующий класс DbParameter. CreatePermission Возвращает новый экземпляра класса поставщика, реализующий версию поставщика класса CodeAccessPermission.
  • 16. Родственные паттерны • Фабричный метод • Прототип • Одиночка
  • 17. Строитель Категория: паттерн, порождающий объекты Назначение: Отделяет алгоритм конструирования сложного объекта от его представления, так что в результате одного и того же процесса конструирования могут получаться совершенно разные представления.
  • 18. Мотивация • Предположим, что процесс инициализации объекта происходит не в одно действие • Часто это является причиной для использования конструктора с пустым набором параметров и инициализации объекта через набор полей Например, HTTP/FTP запрос или ответ 1. Указать заголовки 2. Указать URL запроса 3. Задать тело запроса (если есть).
  • 19. private void RegisterFile(Guid guid, String fileExt) { using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand dbCommand = new SqlCommand("mm_File_Register", connection); dbCommand.CommandType = CommandType.StoredProcedure; dbCommand.Parameters.Add(new SqlParameter("guid", SqlDbType.UniqueIdentifier)); dbCommand.Parameters.Add(new SqlParameter("storage_path", SqlDbType.VarChar, 50)); dbCommand.Parameters.Add(new SqlParameter("profile_name", SqlDbType.VarChar, 256)); dbCommand.Parameters.Add(new SqlParameter("file_ext", SqlDbType.VarChar, 256)); dbCommand.Parameters["guid"].Value = guid; dbCommand.Parameters["storage_path"].Value = FileStorage.BasePath; dbCommand.Parameters["profile_name"].Value = profile; dbCommand.Parameters["file_ext"].Value = fileExt; // Image dbCommand.Connection.Open(); dbCommand.ExecuteNonQuery(); dbCommand.Connection.Close(); } } private bool ConvertOriginal(Stream original, out byte[] bytes) { Image image; var origBytes = ReadAllBytes(original); using (var origStream = new MemoryStream(origBytes)) { try { image = Image.FromStream(origStream); } catch (ArgumentException ex) { throw new BadImageException(ex); } var format = ImageFormat.OriginalImageFormat(image); if (format == null) { bytes = origBytes; return false; } else { var convBytes = ImageConverter.Convert(origStream, format); if (convBytes.Length < origBytes.Length) { bytes = convBytes; return true; } else { bytes = origBytes; return false; } } } }
  • 20. Замечания к примеру • Нарушение принципа единственной ответственности – Создаем хранилище – Преобразование графических данных к указанному формату – Файл с неграфическими данными сохраняется в хранилище под именем “f” c текущим расширением, возможно, здесь добавлено поведение, что может быть только один файл для каждого расширения, а может быть имя файла не так важно, а важен guid, под котором файл зарегистрирован в базе данных • Преобразование графического изображения идет после сохранения в хранилище первого варианта, значит два раза пишем на ftp сервер • Получение расширения по имени файла • Отсутствие транзакционности (можно зарегистрировать файл, но при этом не записать его в хранилище)
  • 21. • Раз объект нельзя проинициализировать в одно действие, то, либо структура объекта сложная (например, составной объект), либо данные, необходимые для инициализации нельзя получить одномоментно (чтение запроса). • Если структура объекта сложная, то она либо будет меняться, а значит и сам алгоритм инициализации, либо будет необходимо иметь несколько различных реализаций (надо избежать copypaste алгоритма инициализации) • Если данные нельзя получить одномоментно, то их необходимо где-то накапливать, чтобы потом создать полностью проинициализированный объект (контрактная модель). • Надо отделить вызов конструктора и передачи в него параметров от алгоритма инициализации.
  • 22. • Весь алгоритм инициализации разбивается на несколько шагов. • Результат каждого шага – изолированная порция информации, необходимая для корректной инициализации конечного объекта • Для примера 2: – – – – Подготовка данных к сохранению, Создать пустой файл Сохранить данные в файл Регистрация файла в базе.
  • 23. Применимость: • Алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой; • Процесс конструирования должен обеспечивать различные представления конструируемого объекта
  • 25. Результаты • • Позволяет изменять внутреннее представление продукта. Класс Builder предоставляет Director интерфейс для конструирования продукта, за которым скрывается внутренняя структура продукта, процесс его сборки. Для повторного использования алгоритма инициализации достаточно лишь определить нового строителя. Изолирует код, реализующий конструирование и представление. Улучшает модульность. Клиенты ничего не знают о классах, определяющих внутреннюю структуру продукта. Управление процессом конструирования. • Побочные эффекты: • – – – Результатом конструирования могут быть совершенно разные объекты, не имеющих между собой ничего общего. Например, 1. матрица – либо сама матрица, либо признак – является она диагональной или нет. 2. Алгоритм конвертера – либо обработанные объявления в базе, либо отчет об ошибках в файл. Иногда Builder используется для оптимизации производительности (StringBuilder из .Net) Упрощает применение Mock объектов при организации модульного тестирования
  • 26. Вопросы реализации • Интерфейс сборки и конструирования – Чаще всего Director не требуется доступ к частям конструируемого объекта, поэтому интерфейс Builder ориентирован только на передачу параметров в одну сторону от Builder к Director – Если же Director такой доступ все же необходим, тогда в интерфейс Builder вводятся методы подсказок о конструируемых частях. Этот случай специфический, поэтому следует применять с крайней осторожностью. • Метод, возвращающий продукт часто бывает не полиморфным, потому что билдеры могут создавать самые разные продукты, сильно отличающиеся друг от друга. Класс продукта обычно жестко привязан к самому билдеру. • Жирные интерфейсы в билдере нежелательны, но допустимы, поскольку набор методов обусловлен алгоритмом инициализации, а не конечным представлением результата иниуциализации.
  • 29. Родственные паттерны • Абстрактная фабрика • Компоновщик (как правило строитель используется для конструирования составных объектов)
  • 30. Прототип • Категория: паттерн, порождающий объекты • Назначение: Задает виды создаваемых объектов с помощью экземпляра-прототипа и создает новые объекты путем копирования этого прототипа
  • 31. Мотивация • Объявление Цель: заявить о чем-либо, чтобы получить желаемую реакцию аудитории • Форма сообщения – Зависит от способа доставки сообщения – Зависит от желания заявителя (например, кредитный калькулятор) • Способ доставки сообщения до потребителя • Проспект – каналы доставки сообщений до целевой аудитории
  • 32. • Рано или поздно функционал стабилизируется (содержание) • Начинает меняться форма Дифференцируйся или умирай! (Джек Траут) MS Office, MS Windows Дизайн Город55 • Внутренняя структура усложняется, часто нет никаких разумных объяснений той или иной структуре Например, необработанные объявления в виде текстовой строки • Создание классов становится неоправданно дорогим • Лучше конфигурировать систему особым образом проинициализированными объектами Например, объявление – структуру полей можно взять из конвертора
  • 33. Применимость • Инстанцируемые классы определяются во время выполнения • Для того, чтобы избежать построения иерархий классов или фабрик, параллельных иерархии классов продуктов • Экземпляры класса могут находится в одном из не очень большого числа различных состояний. Может оказаться удобнее установить соответствующее число прототипов и клонировать их, а не инстанцировать каждый раз класс вручную в подходящем состоянии.
  • 35. Результаты • Те же, что у абстрактной фабрики и строителя • Добавление и удаление продуктов во время выполнения • Спецификация новых объектов путем изменения значений Вместо нескольких классов, создается несколько объектов одного класса, отличающихся своим состоянием Например, объявление • Спецификация объектов путем изменения структуры Например, рубрика параметризуется экземпляром объявления, которое можно подавать в данную рубрику • Уменьшение числа подклассов • Динамическое конфигурирование приложения прототипами
  • 36. Вопросы реализации • Использование диспетчера прототипов (ассоциативный массив, хранящий каждый прототип по ключу) • Реализация операции Clone – Поверхностное и глубокое копирование – IСloneable • Инициализация клонов
  • 37. Известные применения • ArrayList • Метод MemberwiseClone класса object
  • 38. Родственные паттерны • Расширяемая абстрактная фабрика может строиться на основе прототипов • Часто применяется там же, где компоновщик и декоратор.
  • 39. Фабричный метод • Категория: паттерн, порождающий объекты • Назначение: Определяет интерфейс для создания объекта, но оставляет подклассам решение какой класс инстанцировать. • Синоним: Виртуальный конструктор
  • 40. Мотивация • Идея та же, что и для абстрактной фабрики, только класс, в котором размещается фабричный метод, существует для других целей, чем просто создание набора продуктов.
  • 41. Применимость • Классу заранее неизвестно, объекты каких классов ему нужно создавать • Класс спроектирован так, что чтобы объекты, которые он создает, специфицировались подклассами • Класс делегирует обязанности одному из нескольких вспомогательным классов. Необходимо локализовать знание о том, какой класс принимает эти обязанности на себя (например, для определения стратегий)
  • 43. Результаты • Предоставляет классам операции-зацепки (hooks) • Соединяет параллельные иерархии
  • 44. Реализация • Две основных реализации – Creator – абстрактный класс – Creator – конкретный класс • Параметризованные фабричные методы • Generic типы, чтобы не порождать подклассы class Creator<T> { T Create() { return new T(); } } • Extenders .Net можно использовать в качестве фабричных методов • Соглашение об именах
  • 45. Известные применения • DBConnection protected abstract DbCommand CreateDBCommand() • XMLSerialzier.CreateReader protected virtual XmlSerializationReader CreateReader()
  • 46. Родственные паттерны • Абстрактная фабрика часто реализуется с помощью фабричных методов • Фабричные методы часто применяются внутри шаблонных методов, например, для создания стратегий
  • 47. Синглетон • Категория: паттерн, порождающий объекты • Назначение: Гарантирует, что у класса один экземпляр, и предоставляет к нему глобальную точку доступа.
  • 48. Мотивация • Для некоторых классов, важно, чтобы существовал ровно один экземпляр, например, расширяемая фабрика • Если использовать глобальную переменную, то придется явно указывать имя класса, что нарушит открытозамкнутый принцип, кроме того, глобальная переменная не запрещает создавать другие экземпляры. • Класс сам должен контролировать количество экземпляров, которое можно создать. • Контроль возможно осуществлять только из методов.
  • 49. Применимость • Должен быть ровно один экземпляр некоторого класса, легко доступный всем клиентам; • Единственный экземпляр должен расширяться путем порождения подклассов, и клиентам нужно иметь возможность работать с расширенным экземпляром без модификации своего кода.
  • 51. Результаты • Контролируемый доступ к единственному экземпляру • Уменьшение числа имен • Допускает уточнение операций и представления • Допускает переменное число экземпляров • Большая гибкость, чем у операций класса. Паттерн MonoState. Все поля и методы сделать статическими, чтобы гарантировать, что есть ровно один экземпляр. Но тогда нельзя использовать наследование.
  • 52. Реализация • Гарантирование одного экземпляра class Singleton { public static Singleton Instance() { get { return instance; } } private Singleton() { } private static Singleton() { instance = new Singleton(); } private static Singleton instance; }
  • 53. • Порождение подклассов class Singleton { public static void Register(string name, Type type) ,…public static Singleton Instance { get { if(!instance) { instance = CreateInstanceByType(Lookup(Detect())); } return instance; } } private static Type Lookup(name) ,…private static string Detect() ,…- //Определяет имя класса Singleton, которым должна быть сконфигурирована система private static Singleton instance; }
  • 54. • Уничтожение синглетонов – утечка ресурсов – Висячая ссылка Пример: Порядок уничтожения нескольких синглетонов Display, Keyboard, Log Варианты решения: феникс, синглетон с заданной продолжительностью жизни
  • 55. • Феникс interface ISingleton { void DoSometing(); } class Singleton: ISingleton { public static ISingleton Instance { get { if(!instance) { instance = new Singleton(); } return new SingletonPhenix(); } } } class SingletonPhenix: ISingleton { public virtual DoSomething() { Singleton.Instance.DoSomething(); } internal SingletonPhenix(); } • Не хранить ссылки на синглетон, везде использовать вызов свойства Instance • Состояние разрушенного объекта теряется
  • 56. • Синглетон с заданной продолжительностью жизни – Каждому синглетону ставится в соответствие целое число – “продолжительность жизни”. – Список всех синглетонов упорядочивается по продолжительности жизни. – Синглетоны уничтожаются в порядке увеличения продолжительности жизни. – Сам список – это тоже синглетон с наибольшей продолжительностью жизни. – Необходим интерфейс по регистрации синглетонов в общем списке.
  • 57. • Многопоточная среда private static object locker; public static Singleton Instance { lock(locker) { if(!instance) { instance = new Singleton(); } return instance; } } – Неприемлемо из-за больших накладных расходов на блокировку
  • 59. Известные применения • AppDomain public static AppDomain CurrentDomain { get; } • Application public static Application Current { get; }
  • 60. Родственные паттерны • Абстрактная фабрика часто реализуется в виде Синглетона
  • 61. Адаптер • Категория: структурный паттерн • Назначение: преобразует интерфейс одного класса в интерфейс другого, который ожидают клиенты. Адаптер обеспечивает совместную работу классов с несовместимыми интерфейсами, которая без него была бы невозможна. • Синоним: Wrapper(Обертка)
  • 62. Мотивация • Есть готовый класс, который предоставляет нужную функциональность. • Но интерфейс класса не позволяет использовать его непосредственно без изменения. • Если будем переписывать класс, то нет гарантии, что в будущем не возникнет ситуации, когда этот класс не придется приспосабливать под еще один вариант использования. • Согласно открыто-замкнутому принципу, существующий класс модифицировать нельзя. • Выход: создать класс с нужным интерфейсом, но который реализует его через вызов методов существующего класса. Аналог адаптеров в жизни: адаптеры(переходники) для розеток.
  • 63. Применимость: • Надо использовать существующий класс, но его интерфейс не соответствует текущим потребностям • Надо создать повторно используемый класс, который должен взаимодействовать с заранее неизвестными и не связанными с ним классами, имеющими несовместимый между собой интерфейс (Программа Copy, УК 01.001) • (Адаптер объектов) Нужно использовать иерархию классов. Согласно принципу подстановки Лисков адаптер базового класса должен быть написан без знания того, экземпляр какого именно класса он адаптирует. Следовательно, адаптер базового класса можно применить ко всей иерархии классов.
  • 66. Результаты (адаптер объектов) • (+) Один адаптер может применяться ко многим классам (базовый класс и его подклассы). Адаптер добавляет новую функциональность сразу всем адаптируемым классам. • (-) Для замещения операций класса Adaptee надо создать класс производный от Adaptee и сделать так, чтобы адаптер ссылался на этот новый класс
  • 67. Реализация • Объем работы по адаптации • Сменные адаптеры Применяется для уменьшения количества предположений о классах, с которыми взаимодействует данный класс. В такой класс должна быть встроена возможность по адаптации интерфейса. Пример: Универсальная форма по вводу объявлений – Абстрактные операции (лучше не использовать так, как противоречит принципу обращения зависимостей) Пример: специализация формы для каждого вида объявлений – Использование объектов-уполномоченных (улучшение предыдущего подхода, соответствует принципу обращения зависимостей) Пример: Форма использует специальный интерфейс по добавлению полей в каждый вид объявления interface IAd { void Add(Field field); } – Параметризованные адаптеры Пример: биндинг данных на форму, шаблон объявления • Двусторонние адаптеры
  • 69. Известные применения • Adapter Represents a base class for the adapter developed using the WCF LOB Adapter SDK. Namespace: Microsoft.ServiceModel.Channels.Common Assembly: microsoft.servicemodel.channels.dll • Adapter Используется для адаптации логики отдельных элементов. Namespace: Microsoft.Windows.Design.Interaction Assembly: Microsoft.Windows.Design.Extensibility.dll • cHTML Adapter Set The cHTML adapter set renders ASP.NET mobile Web pages on clients that are capable of rendering HTML 3.2 but do not support client scripting. This adapter set includes special support for cHTML, the markup language used on i-mode phones.
  • 70. Родственные паттерны • Мост реализуется аналогично адаптеру, но у моста другое назначение. • Декоратор очень похож на адаптер, но используется подругому.
  • 71. Компоновщик • Категория: паттерн, структурирующий объекты • Назначение: Компонует объекты в древовидные структуры для представления иерархий “part of”. Позволяет клиентам единообразно трактовать индивидуальные и составные объекты.
  • 72. Мотивация • Объекты в программе образуют иерархии “part of”. Например, объявление и поле объявления; поле, в свою очередь может быть составным, например, площадь жилой недвижимости. • Какие иерархии являются “правильными” с точки зрения ООП? • По аналогии с принципом подстановки Лисков: надо единообразно трактовать атомарные и составные объекты. • Значит атомарные и составные объекты должны иметь общий интерфейс
  • 75. Результаты • Определяет иерархии классов, состоящие из примитивных и составных объектов. • Упрощает архитектуру клиента. • Облегчает добавление новых видов компонентов. Изменять клиента при добавлении новых компонентов не нужно. • Способствует созданию общего дизайна. Трудно ограничить, чтобы составной компонент включал только определенные виды компонентов.
  • 76. Реализация • • • • • • • • • Явные ссылки на родителей Разделение компонентов (паттерн Приспособленец) Максимизация интерфейса класса Component Объявление операций для управления потомками (исключение из принципа соответствия интерфейсов, УК 03.001) Должен ли Component реализовывать список компонентов Упорядочивание потомков (паттерн Итератор) Кэширование для повышения производительности Кто должен удалять компоненты Какая структура данных лучше всего подходит для хранения компонентов (паттерн Интерпретатор)
  • 77. Пример кода (ПР 04.008.01-2011)
  • 78. Известные прменения • Control - класс (System.Windows.Controls, System.Web.UI, System.Windows.Forms) • XMLNode (System.XML)
  • 79. Родственные паттерны • Цепочка обязанностей использует паттерн Компоновщик • Декоратор часто совместно используется с компоновщиком • Паттерн приспособленец позволяет разделять компоненты • Итератор может использоваться для обхода составных объектов • Посетитель локализует операции и поведение, которое пришлось бы распределять между классами Composite и Leaf.
  • 80. Фасад • Категория: паттерн, структурирующий объекты • Назначение: Предоставляет унифицированный интерфейс вместо набора интерфейсов некоторой подсистемы. Фасад определяет интерфейс более высокого уровня, который упрощает использование подсистемы.
  • 81. Мотивация • Есть сторонний компонент, который хотелось бы использовать в приложении • Приложение не должно зависеть от используемого компонента • Согласно принципу обращения зависимостей необходимо выделить интерфейсы, которые будет использовать наше приложение и предоставить реализацию этих интерфейсов через сторонний компонент. • Полученный набор классов и будет фасадом.
  • 82. Применимость • Необходимо предоставить интерфейс к сложной подсистеме. Фасад предлагает некоторый вид системы, устраивающий большинство клиентов. И лишь те объекты, которым необходимы более широкие настройки, могут обратиться напрямую к тому, что находится за фасадом. • Между клиентами и классами реализации существует много зависимостей. Фасад позволяет отделить подсистему как от клиентов, так и от других подсистем. • Необходимо разложить систему на отдельные слои. Фасад будет представлять точку входа на каждый отдельный уровень подсистемы.
  • 84. Результаты • Изолирует клиентов от компонентов под системы • Позволяет ослабить связность между под системой и ее клиентами. • Фасад не препятствует приложениям обращаться напрямую к классам подсистемы, если это необходимо.
  • 85. Реализация • Уменьшение степени связности. • Закрытые и открытые классы подсистем.
  • 86. Пример кода (ПР 04.009.01-2011)
  • 87. Известные применения • Платформа .Net – WinForms, WPF – ADO .Net – WCF, Remoting
  • 88. Родственные паттерны • Абстрактная фабрика (для создания фасада, как альтернатива) • Посредник • Адаптер • Декоратор • Синглетон • Мост • Итератор
  • 89. Наблюдатель • Категория: паттерн поведения объектов • Назначение: Определяет зависимость типа “один ко многим” между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом и автоматически обновляются. • Синоним: Dependends (Подчиненные), Publish-Subscribe (издатель-подписчик).
  • 90. Мотивация • Объект класса Subject меняет свое состояние с течением времени • Есть несколько других объектов разных классов, которым необходимо знать об этих изменениях. • Зашивать в код Subject информирование этих объектов об изменении состояния противоречит открыто-замкнутому принципу – могут появиться новые. • Описываем поведение, которое отвечает за информирование объектов в отдельный интерфейс IObserver. • Вызываем методы IObserver из класса Subject.
  • 91. Применимость • У абстракции есть два аспекта, из которых один зависит от другого. Наблюдатель позволяет инкапсулировать эти аспекты в разные объекты и изменять и повторно использовать независимо друг от друга. Пример: объявление, квоты, проверка черных списков • При изменении одного объекта необходимо изменить другие объекты, а их общее количество неизвестно. • Один объект должен оповещать других, не делаю предположений об уведомляемых объектах.
  • 93. Результаты • Абстрактная связность наблюдаемого объекта и наблюдателя Побочные эффекты • Поддержка широковещательных коммуникаций • Неожиданные обновления
  • 94. Реализация • Отображение субъектов на наблюдателей Пример: event предоставляет возможность переопределять механизм подписки с помощью методов Add и Remove Пример: Ex 04.011.01-2011 • Наблюдение более чем за одним объектом Пример: Обработчики событий содержат объект-источник события • Кто инициирует обновление Push и pull-модели получения информации • Как избежать зависимости протокола обновления от наблюдателя: Push и pull-модели получения информации
  • 95. • Висячие ссылки на удаленные наблюдаемые объекты • Гарантия непротиворечивости состояния перед отправкой уведомления Легко нарушить, если вызывать унаследованные методы базового класса из переопределенных методов наследника. class Ad { public virtual void Load() { … Notify(); } } class AutoAd: Ad { public override void Load() { base.Load(); this.model = storage*“model”+; this.marka = storage*“marka”+; } }
  • 96. • Подписка только на интересующие модификации Пример: событийная модель позволяет подписываться только на интересующие события • Комбинирование классов Subject и Observer • Инкапсуляция сложной семантики обновления Нужно: – отношения зависимости между объектами становятся сложными, – Необходимо выполнить серию однотипных обновлений, выполнение обновления выполняется достаточно долго Примеры: 1. Ведение логов. 2. Расчет квот.
  • 97.
  • 98. • Синхронная и асинхронная обработка обновлений GUI обрабатывается в одном потоке • Интеграция приложений
  • 99. Пример кода • Ex 04.010.01-2011 (рекомендации Microsoft по использованию событий) • Ex 04.011.01-2011 (отображение субъекта на наблюдатели)
  • 100. Идеи по проектам • Медленно работает конвертор – Делать проверки для группы объявлений • Фотопроцессор – Сообщение с заданием на конвертацию
  • 101. Известные применения • Обработка событий в любом GUI • Механизм подписки через events и delegates платформы .Net • WPF • Паттерны интеграции корпоративных приложений
  • 102. Родственные паттерны • Команда: обработчики событий • Цепочка ответственности: маршрутизация событий • Посредник: сложные случаи обновления данных
  • 103. Команда • Категория: паттерн поведения объектов • Назначение: Инкапсулирует запрос в виде объекта, позволяя задавать параметры запросов, ставить их в очередь, протоколировать, делать отмену. • Синоним: Action, Transaction.
  • 104. Мотивация • Есть класс, который знает когда нужно выполнить действие, но не знает какое, и есть класс, который знает какое действие выполнить, но не знает, когда Например, текстовое поле • Выделяем интерфейс Command, который описывает поведение Выполнить действие • Тогда класс, который знает когда нужно выполнить действие, может вызывать любое действие не зная сути этого действия.
  • 105. Применимость • Необходимо параметризовать объекты выполняемым действием – альтернатива функциям обратного вызова Пример: – Алгоритм быстрой сортировки – Обработчик событий формы • Определять, ставить запросы в очередь, выполнять в разное время (даже в другом адресном пространстве) • Поддерживать отмену операций • Поддерживать протоколирование изменений • Структурировать систему на основе высокоуровневых операций, построенных из примитивных.
  • 107. Результаты • Разрыв связи между объектом, вызывающим операцию и объектом, знающим, как эту операцию выполнить • Команда – полноценный объект, которым можно манипулировать и расширять Побочные эффекты • Из простых команд можно собирать составные • Добавлять новые команды легко
  • 108. Реализация • Степень смышлености команды Две крайности: – Вызов операций получателя – Самостоятельное выполнение всех операций • Поддержка повтора и отмены операций Дополнительный метод Unexecute Выполняет действие обратное к действию Execute Например: символа ‘a’ в 5 строке 3 символ – удалить 3 символ в пятой строке
  • 109. • Макрокоманды Для реализации применяется паттерн компоновщик Вопросы реализации: – Видит ли следующая команда измененные значения out параметров – Если команды возвращают значение, то что будет возвращать макрокоманда – Если одна из команд генерирует исключение, то продолжать выполнение остальных и, если нет, то следует ли выполнять откат уже выполненных команд? • Накопление ошибок в процессе отмены Сохранять немного больше информации, чем это необходимо для выполнения операции
  • 112. Родственные паттерны • Компоновщик для создания макрокоманд • Хранитель для запоминания информации необходимой для отмены команды • Прототип, если необходимо копировать команду, например, для сохранения в истории • Команда используется совместно с наблюдателем для того, чтобы снизить зависимость наблюдаемого объекта от деталей наблюдателя • Команда используется совместно с цепочкой ответственности, чтобы выбрать наиболее подходящую для выполнения команду
  • 113. Приспособленец • Категория: структурный паттерн • Назначение: Оптимизация использования ресурсов в случае множества мелких объектов
  • 114. Мотивация • Слишком большие расходы на хранение объектов Часто является причиной отказа от ООП • Уменьшить количество объектов до необходимого уровня, путем разделения одного объекта между нескольким сущностями предметной области • Сущности чем-то отличаются между собой • Различие в сущностях выражается в разных значениях данных • Надо придумать способ вычисления данной информации по набору данных, меньшему по объему, чем прямое хранение данных
  • 115. Применимость • большое число объектов, из-за этого накладные расходы на хранение высоки • Большую часть состояния объекта можно вынести вовне • Многие группы объектов можно заменить небольшим количеством разделяемых объектов • Приложение не зависит от идентичности объекта Примеры: Автоматы, схемы электрической цепи (любые диаграммы), векторная графика, текстовый редактор
  • 117. Результаты • Уменьшение объема памяти Побочные эффекты • Сокращение числа экземпляров • Вычисление, а не хранение внешнего состояния
  • 118. Реализация • Управление разделяемыми объектами • Вынесение внешнего состояния
  • 119.
  • 122. Родственные паттерны • Компоновщик. Ациклический направленный граф с разделяемыми листовыми вершинами. • Состояние и стратегия часто реализуются через Приспособленца • Хранитель для сохранения внешнего состояния Приспособленца
  • 123. Хранитель • Категория: паттерн поведения объектов • Назначение: Не нарушая инкапсуляции, выносит за пределы объекта его внутренне состояние, так, чтобы в нем, позднее, можно было восстановить объект. • Синоним: Token.
  • 124. Мотивация • Есть объект Хозяин, состояние которого надо хранить дольше, чем время жизни процесса, его создавшего • При сохранении состояния объекта необходимо иметь доступ ко внутренним данным • Предоставление доступа ко внутренним данным ведет к нарушению инкапсуляции • Выход: создать класс Хранитель, который будет частью реализации объекта Хозяина и который будет заключать в себе внутренне состояние Хозяина. • Чтобы не было нарушения инкапсуляции класс Хранитель должен предоставлять два интерфейса – “открытый” для хранилища, куда будет записываться состояние объекта и “расширенный” – доступный только для Хозяина.
  • 125. Применимость • Необходимо сохранить мгновенный снимок объекта или его части, чтобы потом можно было восстановить в нем объект • Прямой доступ к этому состоянию нарушает инкапсуляцию и раскрывает детали реализации
  • 127. Результаты • Сохранение границ инкапсуляции • Упрощение структуры хозяина • Значительные издержки при использовании хранителей • Скрытая плата за содержание хранителя Побочные эффекты • Определение “узкого” и “широкого” интерфейсов
  • 130. Родственные паттерны • Команда: Хранитель используется для хранения внутреннего состояния команд • Итератор: С помощью итератора осуществляется перебор хранителей в Хранилище • Приспособленец использует Хранителя для манипуляции состояния, выносимого за пределы приспособленца
  • 131. Шаблонный метод • Категория: паттерн поведения объектов • Назначение: Определяет основу алгоритма и позволяет подклассам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом.
  • 132. Мотивация • Несколько функций концептуально похожи друг на друга, но отличаются вызываемыми функциями, или есть длинный метод. • Выделяем набор блоков, в каждой из функций. • Каждый из этих блоков оборачиваем вызовом операции. • Полученные операции образуют набор примитивных операций и функций-зацепок. • Преобразованный метод реализует паттерн Шаблонный метод.
  • 133. Применимость • Повторно использовать неизменные части алгоритма, позволяя подклассам переопределять реализацию изменяющегося поведения • Для управления расширениями подклассов. Точки расширения – функции-зацепки.
  • 134. Результаты • Шаблонные методы приводят к инвертированной структуре кода (принцип обращения зависимостей) • Шаблонные методы вызывают операции следующих видов: – – – – – Конкретные операции (из ConcreteClass, либо из клиента) Конкретные операции из AbstractClass Примитивные операции Фабричные методы Операции-зацепки (операции, имеющие реализацию по умолчанию, которые могут быть переопределены в подклассах)
  • 136. Реализация • Контроль доступа (видимость, абстрактные операции) • Сокращение числа примитивных операций • Соглашение об именах Например, имена замещаемых операций начинаются с префикса Do
  • 137. Пример кода • Ex 04.015.01-2011
  • 138. Известные применения • XpathNavigator (System.XML.XPath) – – – – – – – – – – – – – – – – – – – – – NameTable Clone NodeType LocalName Name NamespaceURI Prefix BaseURI IsEmptyElement MoveToFirstAttribute MoveToNextAttribute MoveToFirstNamespace MoveToNextNamespace MoveToNext MoveToPrevious MoveToFirstChild MoveToParent MoveTo MoveToId IsSamePosition Value – – – – AppendChild CreateAttribute CreateAttributes CreateNavigator
  • 139. Родственные паттерны • Фабричные методы часто вызываются в шаблонах • Стратегии применяются для делегирования модификации алгоритма в целом
  • 140. Стратегия • Категория: паттерн поведения объектов • Назначение: Определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. • Синоним: Policy (Политика).
  • 141. Мотивация • Есть несколько операторов switch или цепочек if-else-if • Такие конструкции противоречат Открыто-замкнутому принципу, так как делают программу нерасширяемой • Заменим каждый switch или цепочку if-else-if на полиморфную операцию • Необходимо гарантировать, что определенные реализации виртуальных функций используются совместно • Перенесем все выделенные операции в один интерфейс. • Те реализации функций, которые должны использоваться совместно реализуем в одном классе-наследнике от выделенного интерфейса.
  • 142. Применимость • Имеется много родственных классов, отличающихся только поведением • Необходимо иметь несколько вариантов алгоритма • В алгоритме содержатся данные, о которых клиент не должен знать • В классе определено много поведений, которые представлены разветвленными условными операторами
  • 144. Результаты • Семейства родственных алгоритмов • Альтернатива порождению подклассов • С помощью стратегий можно избавиться от условных операторов • Выбор реализации Побочные эффекты • Клиенты должны знать о различных стратегиях • Увеличение числа объектов • Обмен информацией между стратегией и контекстом
  • 145. Реализация • Обмен данными между стратегией и контекстом • Стратегии как параметры generic-типов
  • 146. Пример кода • Ex 04.016.01-2011 • Ex 04.017.01-2011
  • 148. Родственные паттерны • Объекты-стратегии удобно реализовывать в виде приспособленцев • Стратегии используются для параметризации шаблонного метода
  • 149. Посредник • Категория: паттерн поведения объектов • Назначение: Определяет объект, инкапсулирующий способ взаимодействия множества объектов. Посредник обеспечивает слабую связность, избавляя компоненты от необходимости явно ссылаться друг на друга. • Синоним: Controller (Контроллер).
  • 150. Мотивация • В системе много классов, которые сильно связаны между собой (каждый с каждым). • Получаем нарушение открыто-замкнутого принципа. • Идея: прием как в случае отношения “многие-ко-многим” – создать объект, с которым будут взаимодействовать все остальные. • Тогда все остальные объекты можно использовать повторно.
  • 151. Применимость • Имеются объекты, связи между которыми сложны и нечетко определены, взаимозависимости трудны для понимания. • Нельзя повторно использовать объект, поскольку он обменивается информацией с другими объектами. • Поведение, распределенное между несколькими классами, должно поддаваться настройке без порождения подклассов.
  • 153. Результаты • Устраняет связность между коллегами • Упрощает протоколы взаимодействия объектов • Абстрагирует способ кооперирования объектов Побочный эффект • Централизует управление • Снижает число порождаемых подклассов
  • 154. Пример кода • Ex 04.018.01-2011
  • 155. Известные применения • MVC (ASP .Net MVC Framework, BL) • Форма приложения часто является посредником для своих дочерних элементов
  • 156. Родственные паттерны • Фасад часто реализуется как совокупность посредников. • Посредник может быть реализован в виде наблюдателя по отношению к коллеге-инициатору взаимодействия и в виде наблюдаемого объекта по отношению к коллегеконечной точке взаимодействия. • Коллеги могут быть реализованы в виде приспособленцев, в этом случае посредник занимается инициализацией состояния приспособленцев, хранимой вовне.
  • 157. Декоратор • Категория: паттерн структурирующий объекты • Назначение: Динамически добавляет объекту новые обязанности. Альтернатива порождению подклассов. • Синоним: Wrapper (Обертка).
  • 158. Мотивация • • • • • • • Есть иерархия классов, ко всем объектам которой необходимо добавить дополнительное поведение на время выполнения одной операции. Модифицировать базовый класс нельзя, так как нарушим открытозамкнутый принцип. Значит надо создать новый класс. Чтобы не нарушить принцип подстановки Лисков, надо чтобы новый класс мог быть использован всеми клиентами без явной ссылки на этот класс. Это можно сделать, только если класс реализует тот же самый интерфейс, что и базовый класс иерархии. Чтобы не дублировать поведение существующих классов, новый должен реализовывать только новое поведение самостоятельно, а остальное – делегировать уже существующим классам. Это возможно, если новый класс будет хранить ссылку на декорируемый объект и делегировать ему выполнение всех операций.
  • 159. Применимость • Динамическое, прозрачное для клиентов добавление обязанностей • Реализация обязанностей, которая может быть снята с клиента. • Замена расширения с помощью подклассов.
  • 161. Результаты • Большая гибкость, чем у статического наследования. • Уменьшает количество перегружаемых функций на верхних уровнях иерархии классов. Побочные эффекты: • Декоратор и его компонент не идентичны. • Множество мелких объектов.
  • 162. Реализация • • • • Соответствие интерфейсов Отсутствие абстрактного класса декоратор Облегченные классы Component Изменение внешнего поведения, а не реализации
  • 164. Известные применения • System.Reflection.TypeDelegator protected Type typeImpl • ReadOnly коллекции public static IList ArrayList.ReadOnly( IList list ); • Исправление ошибки в библиотеке работы с MySQL на Qt3
  • 165. Родственные паттерны • Адаптер vs. Декоратор • Декоратор можно реализовывать как – Singleton – Flyweight
  • 166. Итератор • Категория: паттерн поведения объектов • Назначение: Предоставляет доступ ко всем элементам составного объекта, не раскрывая его внутреннего состояния. • Синоним: Cursor.
  • 167. Мотивация • Есть алгоритм, который перебирает элементы некоторого составного объекта • Способ перебора элементов – это деталь реализации составного объекта • Если алгоритм будет зависеть от деталей реализации перебираемого им составного объекта, то его придется переписывать каждый раз, когда меняется реализация этого объекта. • Согласно принципу обращения зависимостей мы должны определить интерфейс перебора составного объекта и через него реализовать алгоритм, а составному объекту дать возможность реализовать этот интерфейс. • Выделенный интерфейс и будет иетратором.
  • 168. Применимость • Доступ к содержимому составных объектов, не раскрывая деталей реализации. • Несколько активных обходов одного составного объекта • Единообразный интерфейс обхода для разных составных объектов.
  • 170. Результаты • Различные виды обходов составного объекта • Упрощение интерфейса составного объекта • Несколько активных обходов одного и того же составного объекта Побочный эффект • Изменение в структуре составного объекта может повлиять на активные обходы
  • 171. Реализация • С++ и Java-стиль итераторов – С++-стиль ContainerType C; // Любой стандартный тип контейнера, например std::list<sometype> //for (ContainerType::iterator it = C.begin(),end = C.end(); it != end; ++it) //(если вам нужно изменять элементы) for (ContainerType::const_iterator it = C.begin(),end = C.end(); it != end; ++it) { std::cout << *it << std::endl; } ContainerType<ItemType> C; // Любой стандартный тип контейнера элементов ItemType void ProcessItem( const ItemType& I ) // Функция, обрабатывающая каждый элемент коллекции { std::cout << I << std::endl; } std::for_each( C.begin(), C.end(), ProcessItem ); // Цикл просмотра
  • 172. – Java-стиль // 'явная' версия IEnumerator<MyType> iter = list.GetEnumerator(); while (iter.MoveNext()) { Console.WriteLine(iter.Current); } // 'неявная' версия foreach (MyType value in list) { Console.WriteLine(value); }
  • 173. • Внешние и внутренние – Внешние рассмотрены выше – Внутренние AdsGrid grid = new AdsGrid(); grid.MoveToFirst(); while(grid.IsLast()) { doSomething(grid.Current()); } Закладки – обеспечение нескольких активных просмотров одновременно AdsGrid grid = new AdsGrid(); grid.MoveToFirst(); while(!grid.IsLast()) { Log(grid); doSomething(grid.Current()); grid.MoveToNext(); }
  • 174. void Log(AdsGrid grid) { grid.MoveToFirst(); while (!grid.IsLast()) { LogOneRecord(grid.Current()); grid.MoveToNext(); } } Решение class Bookmark: IDisposable { private GridCursor old; private AdsGrid grid; public Bookmark(AdsGrid grid) { old = grid.Current(); this.grid = grid; } public void Dispose() { grid.SetCursor(old); } }
  • 175. AdsGrid grid = new AdsGrid(); using (Bookmark bookmark = new Bookmark(grid)) { grid.MoveToFirst(); while(!grid.IsLast()) { Log(grid); doSomething(grid.Current()); grid.MoveToNext(); } } void Log(AdsGrid grid) { using (Bookmark bookmark = new Bookmark(grid)) { grid.MoveToFirst(); while (!grid.IsLast()) { LogOneRecord(grid.Current()); grid.MoveToNext(); } } }
  • 176. • Набор методов итератора – Для чтения public T Current { get; } – Для записи public T Current { get; } – Односторонний public bool MoveNext(); – Двусторонний public bool MovePrevious(); – С произвольным доступом public T this[int index] { get; }
  • 177. • • • • Полиморфные итераторы Устойчивость итератора к изменениям контейнера Доступ ко внутреннему представлению контейнера Итераторы и составные объекты – Несколько уровней вложенности – Несколько способов обхода • Пустые итераторы Могут применяться вместе паттерном компоновщик для листовых элементов древовидных структур
  • 179. Известные применения • IEnumerator<T> (System.Collections.Generic) • DbDataReader (System.Data.Common) • Stream (System.IO)
  • 180. Родственные паттерны • Часто используются совместно с компоновщиком для составных объектов • Фабричный метод для создания полиморфных итераторов (GetEnumerator()) • Хранитель для сохранения состояния итератора (Закладка для внутренних итераторов)
  • 181. Состояние • Категория: паттерн поведения объектов. • Назначение: Изменение поведения в зависимости от внутреннего состояния объекта.
  • 182. Мотивация • Объект может пребывать в нескольких состояниях (установка соединения, запущен, приостановлен, запускается, остановлен и т.д.) • От этих состояний зависит поведение объекта, причем поведение может очень сильно отличаться • У объекта могут появляться новые состояния, либо меняться переходы между существующими • Локализуем поведение каждого из состояний внутри отдельного класса.
  • 183. Применимость • Поведение объекта зависит от состояния, которое должно меняться динамически • В коде много последовательностей if-else-if, выбор веток которых зависит от состояния объекта
  • 185. Результаты • Локализует, зависящее от состояние поведение в отдельных классах, разбивая его тем самым на части, каждая из которых соответствует одному состоянию. • Явные переходы между состояниями Побочные эффекты • Объекты состояния можно разделять (Flyweight)
  • 186. Реализация • • • • Кто должен определять переход между состояниями Таблица переходов между состояниями Создание и уничтожение объектов состояния Использование динамического наследования
  • 188. Известные применения • WWF • • • • Windows сервисы Потоки Сокеты Соединения
  • 189. Родственные паттерны • Приспособленец для разделения объектов состояния • Состояние часто реализуется в виде одиночки • Состояние может реализовываться в виде команды или последовательности команд
  • 190. Цепочка ответственности • Категория: паттерн поведения объектов. • Назначение: Позволяет избежать привязки отправителя запроса к его получателю, давая шанс обработать его нескольким объектам.
  • 191. Мотивация • Есть запрос, который должен обработать один из множества, возможно динамического, объектов • Поскольку количество объектов нам неизвестно, то должна быть динамическая структура данных, позволяющая хранить в себе все это множество • Объекты имеют разную природу, следовательно, чтобы их унифицировать для обработки сообщений, надо, чтобы они реализовывали один и тот же интерфейс. • Чтобы клиент не пришлось перебирать все множество объектов-получателей запроса, нужно предоставить им самим принимать решение – кто будет обрабатывать запрос
  • 192. Применимость • Есть более одного объекта, способного обработать запрос, причем обработчик заранее неизвестен • Необходимо отправить запрос одному из нескольких объектов, не указывая, какому именно • Набор объектов способных обработать запрос, должен задаваться динамически
  • 194.
  • 195. Результаты • ослабление связанности • дополнительная гибкость при распределении обязанностей “-” • получение сообщения не гарантировано • Замедление работы приложения, в случае, если цепочки будут слишком длинными, а сообщений много (Qt 4.*)
  • 196. Реализация • Цепочка приемников – На основе существующих связей (например, ссылки, используемые Компоновщиком) – Организация новых связей • Реализация обработчика по умолчанию • Представление запросов – Один запрос – функция обработчик – Много запросов – запрос-объект • Автоматическое перенаправление запросов (PHP, Javascript)
  • 197. Пример кода • Ex 04.021.01-2011
  • 198. Известные применения • GUI, Web-интерфейс • WWF, WinForms • ASP .Net MVC, Ruby on Rails, Zend Framework • Фильтры сообщений • System.Collections.Concurrent.ConcurrentQueue<T> • Message Queue
  • 199. Родственные паттерны • Часто применяется совместно с паттерном компоновщик • Обработка запросов осуществляется паттерном команда
  • 200. Заместитель • Категория: паттерн структурирующий объекты. • Назначение: Является суррогатом другого объекта и контролирует доступ к нему. • Синоним: Surrogate
  • 201. Мотивация • Есть уже готовый класс, понадобилась возможность разграничения доступа. Часть методов данного класса может быть недоступно, в зависимости от набора прав. • Разбивать класс на несколько в соответствии с правами доступа – нарушение открыто-замкнутого принципа, кроме того, права могут меняться. • Создать класс с тем же интерфейсом, что и исходный, только при вызове каждого метода будет проверяться права доступа, и в случае, если прав достаточно – вызывать метод исходного объекта.
  • 202. Применимость • “Посол”. Локальный представитель вместо объекта находящегося в другом адресном пространстве. (WCF, .Net Remoting) • “Виртуальный заместитель”. Создает “тяжелые” объекты по требованию. (Например, картинка, отложенные вычисления, ленивая инициализация) • “Защищающий” заместитель. Контролирует доступ к исходному объекту. (Разграничение прав доступа). • “Умная ссылка” – Подсчет числа ссылок на реальный объект. Например, копирование при записи. – Загрузка объекта в память при первом обращении к нему – Проверка и установка блокировки на реальный объект при первом обращении к нему
  • 204. Результаты Зависят от типа Прокси • Посол скрывает факт удаленности объекта • Виртуальные заместители выполняют оптимизацию • Защищающий заместитель и умная ссылка решают дополнительные задачи при доступе к объекту
  • 205. Реализация • Заместителю не всегда должен быть известен тип реального объекта • Как обращаться к еще не инстанцированному объекту?
  • 206. Пример кода • Ex 04.022.01-2011 • Ex 04.023.01-2011
  • 207. Известные применения • Ссылка на объект в .Net • WCF, .Net Remoting
  • 208. Родственные паттерны • Адаптер vs. Заместитель • Декоратор vs. Заместитель
  • 209. Посетитель • Категория: паттерн поведения объектов. • Назначение: Описывает операцию, выполняемую объектом некоторой структуры.
  • 210. Мотивация • Есть некоторый составной объект, процедура обхода которого достаточно сложна • Есть несколько операций по данному объекту, которые используют данную процедуру обхода. Необходимо повторно использовать процедуру обхода для выполнения всех операций • Надо отделить саму процедуру обхода от операций, которые выполняются во время обхода, выделив их в отдельный интерфейс. • Каждая операция, как правило применяется как какого-нибудь элементу составного объекта, поэтому добавим в интерфейс по одному методу на каждый элемент, который мы достигаем при обходе. • Раскладываем каждую операцию по методам интерфейса.
  • 211. Применимость • Объект включает в себя объекты многих классов, а выполняемая операция должна зависеть от классов этих объектов. • Над объектами, входящими в состав сложный структуры, надо выполнять различные операции и не хочется добавлять эти операции в классы данных объектов – иначе нарушим принцип соответствия интерфейсов. • Классы объектов структуры меняются редко, а операции над объектами добавляются часто.
  • 213. Результат • Упрощает добавление новых операций • Объединяет родственные операции и отсекает те, которые не имеют никакого отношения • Посещение различных иерархий классов • Аккумулирование состояния “-” • Добавление новых классов затруднено • Нарушение инкапсуляции
  • 214. Реализация • Двойная диспетчеризация • Какой участник несет ответственность за обход структуры
  • 215. Пример кода • Ex 04.024.01-2011
  • 216. Известные применения • XML сериализация public class MyClass { public MyObject MyObjectProperty; } public class MyObject { public string ObjectName; } <MyClass> <MyObjectProperty> <ObjectName>My String</ObjectName> </MyObjectProperty> </MyClass> • XPathNavigator (System.XML.Xpath) XPathDocument document = new XPathDocument("books.xml"); XPathNavigator navigator = document.CreateNavigator(); XPathExpression query = navigator.Compile("/bookstore/book"); XPathNodeIterator nodes = navigator.Select(query); XPathNavigator nodesNavigator = nodes.Current; XPathNodeIterator nodesText = nodesNavigator.SelectDescendants(XPathNodeType.Text, false); while (nodesText.MoveNext()) { Console.WriteLine(nodesText.Current.Value); }
  • 218. Паттерн Мост • Категория: паттерн структурирующий объекты. • Назначение: Отделить абстракцию от реализации, так чтобы ее можно менять независимо. • Описание: HandleBody (ОписательТело)
  • 219. Мотивация • В зависимости от внешних факторов у класса может быть разная реализация • Разницу в реализации описывать if-else-if нельзя, так нарушит отрыто-замкнутый принцип • Надо каждую из реализаций представить в виде отдельного класса Implementor • Для пользователя выбор реализации должен быть прозрачен – значит надо скрыть факт различия реализаций за специальным классом Handle