- •Лабораторная работа №4 Шаблоны проектирования
- •Теоретические сведения
- •Отношения между классами. На диаграммах классов языка uml
- •Суть паттерна
- •Решение
- •Адаптер объектов
- •Адаптер классов
- •Адаптер классов не нуждается во вложенном объекте, так как он может одновременно наследовать и часть существующего класса, и часть сервиса.
- •Фасад (Facade)
- •Концептуальный пример
- •Program.Cs:
- •Output.Txt: Результат выполнения
- •Изолирует клиентов от компонентов подсистемы Уменьшая тем самым число объектов, с которыми клиентам приходится иметь дело, упрощая работу с подсистемой.
- •Позволяет ослабить связанность между подсистемой и ее клиентами.
- •Фасад не исключает возможности приложениям напрямую обращаться к классам подсистемы, если это необходимо.
- •Заместитель (Proxy)
- •3. Локальный запуск сервиса (удалённый прокси). Когда настоящий сервисный объект находится на удалённом сервере.
- •Концептуальный пример
- •Декоратор (Decorator)
- •// Объект
- •} //Ptr2 выходит из области видимости, но объект не //освобождается, потому что есть ptr, который по-прежнему //ссылается на него } //ptr выходит из области видимости, и объект уничтожается
- •Пример на языке c#
- •Порождающие шаблоны Абстрактная фабрика (Abstract Factory)
- •1. Шаблон реализуется созданием абстрактного класса Factory, который представляет собой интерфейс для создания компонентов системы.
- •3. Таким образом, еще раз - предоставляет интерфейс для создания семейств, связанных между собой, или зависимых объектов.
- •Клиент пользуется только интерфейсами, заданными в классах «Абстрактная фабрика» и «Абстрактный продукт».
- •Фабричный метод (Factory Method)
- •Void info() {
- •Void info() {
- •Void info() {
- •Int main()
- •Одиночка (Singleton) Суть паттерна
- •If(!p_instance)
- •Поведенческие шаблоны Стратегия (Strategy)
- •Стратегии построения пути.
- •Структура
- •Концептуальный пример
- •Program.Cs: Пример структуры паттерна
- •Output.Txt: Результат выполнения
- •Void useStrategy(void)
- •Void setStrategy(Strategy* o)
- •Int main(int /*argc*/, char* /*argv*/[])
- •Наблюдатель (Observer) Суть паттерна
- •Решение
- •Структура
- •Шаги реализации
- •Концептуальный пример
- •Program.Cs: Пример структуры паттерна
- •// Random.Next(…) - Метод, возвращает случайное целое число //в указанном диапазоне.
- •Output.Txt: Результат выполнения
- •Использование паттерна Observer
- •Команда (Command)
- •Структура
- •Output.Txt: Результат выполнения
- •Задания для лабораторной работы
Void info() {
cout << "Person1" << endl;
};
};
class Person2: public Bas_per
{
public:
Void info() {
cout << "Person2" << endl;
};
};
class Person3: public Bas_per
{
public:
Void info() {
cout << "Person3" << endl;
};
};
// Фабрика объектов
class Factory
{
public:
virtual Bas_per* createPer() = 0;
virtual ~Factory() {}
};
class P1Factory: public Factory
{
public:
Bas_per* createPer() {
return new Person1;
}
};
class P2Factory: public Factory
{
public:
Bas_per* createPer() {
return new Person2;
}
};
class P3Factory: public Factory
{
public:
Bas_per* createPer() {
return new Person3;
}
};
// Создание объектов при помощи фабрик объектов
Int main()
{
P1Factory* person1_factory = new P1Factory;
P2Factory* person2_factory = new P2Factory ;
P3Factory* person3_factory = new P3Factory ;
vector<Bas_per*> v;
v.push_back( person1_factory->createPer());
v.push_back( person2_factory->createPer());
v.push_back( person3_factory->createPer());
for(int i=0; i<v.size(); i++)
v[i]->info();
// ...
}
Достоинства
- позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам (ConcreteProduct), а оперируя лишь общим интерфейсом (Product);
- позволяет установить связь между параллельными иерархиями классов.
Недостатки
- необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct).
========================================
Одиночка (Singleton) Суть паттерна
Одиночка — это порождающий паттерн проектирования, который гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа
Одиночка — порождающий шаблон проектирования, гарантирующий, что в однопоточном приложении будет единственный экземпляр класса с глобальной точкой доступа.
Из всех паттернов Одиночка имеет самую простую диаграмму классов. Однако, несмотря на его простоту в его реализации кроется немало ловушек.
Паттерн Singleton часто называют усовершенствованной глобальной переменной.
Назначение паттерна Singleton
- Часто в системе могут существовать сущности только в единственном экземпляре, например, система ведения системного журнала сообщений или драйвер дисплея.
- К таким объектам можно отнести: пулы программных потоков, кэши, диалоговые окна, драйвера устройств и др.
- Для таких объектов попытка создать более одного объекта приводит к некорректному поведению программы, к лишним затратам ресурсов или к нелогичным результатам.
- В таких случаях необходимо уметь создавать единственный экземпляр некоторого типа, предоставлять к нему доступ извне и запрещать создание нескольких экземпляров того же типа.
Паттерн Singleton предоставляет такие возможности.
Казалось бы, можно воспользоваться глобальной переменной, которая предоставляет глобальную точку доступа к данным.
«Одиночка» избавлен от недостатков глобальной переменной.
Главный из них тот, что, если объект присваивается глобальной переменной и, как правило, вначале программы и объект расходует много ресурсов, а может никогда не использоваться приложением.
Паттерн Одиночка позволяет создавать объекты в тот момент, когда они нужны (отложенная инициализация)
В таких случаях необходимо уметь создавать единственный экземпляр некоторого типа, предоставлять к нему доступ извне и запрещать создание нескольких экземпляров того же типа.
Для решения задачи необходимо разбираться в статических методах и переменных, а также в модификаторах доступа.
Паттерн Singleton предоставляет такие возможности.
Описание паттерна Singleton
Архитектура паттерна Singleton основана на идее использования глобальной переменной, имеющей следующие важные свойства:
- Такая переменная доступна всегда. Время жизни глобальной переменной - от запуска программы до ее завершения.
- Предоставляет глобальный доступ, то есть, такая переменная может быть доступна из любой части программы.
- Однако, использовать глобальную переменную некоторого типа непосредственно невозможно, так как существует проблема обеспечения единственности экземпляра, а именно, возможно создание нескольких переменных того же самого типа (например, стековых).
Для решения этой проблемы паттерн Singleton возлагает контроль над созданием единственного объекта на сам класс.
1) Доступ к этому объекту осуществляется через статическую функцию-член класса, которая возвращает указатель или ссылку на него.
Этот объект будет создан только при первом обращении к методу, а все последующие вызовы просто возвращают его адрес.
2) Для обеспечения уникальности объекта, конструкторы и оператор присваивания объявляются закрытыми.
Для некоторых классов важно, чтобы существовал только один экземпляр.
При этом сам класс контролирует то, что у него есть только один экземпляр, может запретить создание дополнительных экземпляров, перехватывая запросы на создание новых объектов, и он же способен предоставить доступ к своему экземпляру.
3) «Одиночка» определяет операцию getInstance(), которая позволяет клиентам получать доступ к единственному экземпляру.
Клиенты имеют доступ к «Одиночке» только через эту операцию.
Паттерн позволяет избежать засорения пространства имен глобальными переменными, в которых хранятся уникальные экземпляры.
4) Реализуется одиночка обычно с помощью статического метода класса, который имеет доступ к переменной, хранящей уникальный экземпляр, и гарантирует инициализацию переменной этим экземпляром перед возвратом ее клиенту.
Наиболее часто встречающуюся реализацию паттерна Singleton.
// Singleton.h
class Singleton
{
private:
static Singleton * p_instance;
//другие данные
// Конструкторы и оператор присваивания недоступны клиентам
Singleton () {}
Singleton (const Singleton&);
Singleton& operator= (Singleton&);
public:
static Singleton * getInstance() {
