Шаблоны проектирования: Учебник
Шаблоны проектирования: Учебник
Швец Александр - Погружение в паттерны проектирования - 2021

- Вложения
-
- 1f44966179ff176587d338dd0b837291.jpg
- (66.21 КБ) 0 скачиваний
- 1f44966179ff176587d338dd0b837291.jpg
- (66.21 КБ) 0 скачиваний
-
- ShvetsA_PogrujenieVPatternyProektirovaniya-2021.pdf
- Швец Александр - Погружение в паттерны проектирования - 2021
- (28.2 МБ) 11290 скачиваний
- ShvetsA_PogrujenieVPatternyProektirovaniya-2021.pdf
- Швец Александр - Погружение в паттерны проектирования - 2021
- (28.2 МБ) 11290 скачиваний
Re: Шаблоны проектирования: Учебник
Миллетт С., Тьюн Н. - Предметно-ориентированное проектирование. Паттерны, принципы и методы (Для профессионалов) - 2017
- Вложения
-
- Milet_Tiun-PredmetnoOrientirovannoeProektirovatie-2017.pdf
- Миллетт С., Тьюн Н. - Предметно-ориентированное проектирование. Паттерны, принципы и методы (Для профессионалов) - 2017
- (25.14 МБ) 8436 скачиваний
- Milet_Tiun-PredmetnoOrientirovannoeProektirovatie-2017.pdf
- Миллетт С., Тьюн Н. - Предметно-ориентированное проектирование. Паттерны, принципы и методы (Для профессионалов) - 2017
- (25.14 МБ) 8436 скачиваний
Re: Шаблоны проектирования: Учебник
Могелашвили - Паттерны проектирования
https://e19.hardprivate.com/Mogeashvilly_PatternyProektirovaniya.zip
https://e19.hardprivate.com/Mogeashvilly_PatternyProektirovaniya.zip
Re: Шаблоны проектирования: Учебник
Шаблон проектирования Фабричный метод (порождающий шаблон)
Код: Выделить всё
#include <iostream>
using namespeace std;
//Интерфейс абстрактного продукта
class IProduction
{
public:
virtual viod release() = 0;
};
//Конкретный продукт реализует интерфейс продукта:
class Car : public IProduction
{
public:
void release() override
{
cout << "Выпущен новый автомобиль" << endl;
}
};
class Truck : public IProduction
{
public:
void release() override
{
cout << "Выпущен грузовой автомобиль" << endl;
}
};
//Интерфейс абстрактного цеха, производящий автомобили
class IWorkShop
{
public:
// Создаёт абстрактный автомобиль
virual IProduction* create() = 0;
};
//Конкретный цех по производству автомобилей
class CarWorkShop : public IWorkSop
{
public:
IProduction* create() override
{
return new Car();
}
};
class TrackWorkShop : public IWorkSop
{
public:
IProduction* create() override
{
return new Truck();
}
};
int main()
{
setlocale(LC_ALL, "rus");
//Экземпляр цеха по производству легковых автомобилей
IWorkSop* creator = new CarWorkShop();
//Создаст легковой автомобиль
IProduction* car = creator->create();
//Переквалифицируем цех на производство грузовых автомобилей
creator = new TruckWorkShop();
//Создадим грузовой автомобиль
IProduction* truck = creator->create();
//Выпуск созданных автомобилей
car->release();
truck->release();
//Высвобождаем память
car = delete;
truck = delete;
return 0;
}
Re: Шаблоны проектирования: Учебник
Абстрактная фабрика (порождающий шаблон)
Применяется: когда программа должна быть независима от процессов и типов создаваемых объектов, а так же когда необходимо создать семейство или группы взаимосвязанных объектов.
Достоинства:
1. изолирует конкретные классы
2. упрощает замену семейств продуктов
3. гарантируется читаемость продуктов
Недостатки:
1. Сложность добавления нового вида продуктов
Применяется: когда программа должна быть независима от процессов и типов создаваемых объектов, а так же когда необходимо создать семейство или группы взаимосвязанных объектов.
Достоинства:
1. изолирует конкретные классы
2. упрощает замену семейств продуктов
3. гарантируется читаемость продуктов
Недостатки:
1. Сложность добавления нового вида продуктов
Код: Выделить всё
#include <iostream>
using namespace std;
class IEngine
{
public:
virtual void releaseEngine() = 0;
};
class JapaneseEngine : public IEngine
{
public:
void releaseEngine() override
{
cout << "японский двигатель" <<endl;
}
};
class RussianEngine : public IEngine
{
public:
void releaseEngine() override
{
cout << "российский двигатель" <<endl;
}
};
class ICar
{
public:
virtual void releaseCar(IEngine* engine) = 0;
}
class JapaneseCar : public ICar
{
public:
void release(IEngine* engine) override
{
cout << "Собрали японский автомобиль: " << endl;
engine->releaseEngine();
}
};
class RussianCar : public ICar
{
public:
void release(IEngine* engine) override
{
cout << "Собрали российский автомобиль: " << endl;
engine->releaseEngine();
}
};
class IFactory
{
public:
virtual IEngine* createEngine() = 0;
virtual ICar* createCar() = 0;
};
class JapaneseFactory : public IFactoru
{
public:
IEngine* createEngine() override
{
return new JapaneseEngine();
}
ICar* createCar() override
{
return JapaneseCar();
}
};
class RussianFactory : public IFactoru
{
public:
IEngine* createEngine() override
{
return new RussianEngine();
}
ICar* createCar() override
{
return RussianCar();
}
};
int main()
{
setlocale(LC_ALL, "rus");
IFactory* jFactory = new JapanesFactory();
IEngine* jEngine = jFactory->createEngine();
ICar* jCar = jFactory->createCar();
jCar->releaseCar(jEngine);
IFactory* rFactory = new RussianFactory();
IEngine* rEngine = rFactory->createEngine();
ICar* rCar = rFactory->createCar();
rCar->releaseCar(rEngine);
return 0;
}
Re: Шаблоны проектирования: Учебник
Строитель (пораждающий шаблон) - предоставляет способ создания составного объекта
отделяет конструирование сложного объекта от его представления, так что в результате одного и того же конструирования могут получаться разные представления
Достоинства:
позволяет изменять внутреннее представление продукта
изолирует код, реализующий конструирование и представление
даёт более тонкий контроль над процессом конструирования
алгоритм создания не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой
отделяет конструирование сложного объекта от его представления, так что в результате одного и того же конструирования могут получаться разные представления
Достоинства:
позволяет изменять внутреннее представление продукта
изолирует код, реализующий конструирование и представление
даёт более тонкий контроль над процессом конструирования
алгоритм создания не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой
Код: Выделить всё
#include <iosteream>
#include <string>
using namespeace sts;
//Телефон - результат производства нашей системы
class Phone
{
string data;
public:
Phone()
{
data = "";
}
string aboutPhone()
{
return data;
}
//Открытый метод, через аргумент которой будет добавляться информация о той или иной стадии производства телефона
void appendData(string str)
{
data += str;
}
};
//Интерфейс разработчика телефонов, который по контракту может:
// 1. создать дисплей телефонов
// 2. создавать корпус телефона
// 3. устанавливать операционную систему
// 4. по результатам разработки представлять разработанный им телефон через метод getPhone()
class IDeveloper
{
public:
virtual void createDisplay() = 0;
virtual void createBox() = 0;
virtual void systemInstall() = 0;
virtual Phone* getPhone() = 0;
};
// Конкретный класс разработчика телефона на платформе андройд
class AndroidDeveloper : public IDeveloper
{
private:
Phone* phone;
public:
//Инициализация приватного свойства phone в открытом конструкторе
AndroidDeveloper()
{
phone = new Phone();
}
//в деструкторе класса, указать свойства phone, будет уничтожаться, освобождая память
~AndroidDeveloper()
{
delete phone;
}
//Реализуем все методы интерфейса IDeveloper
void createDisplay() override
{
phone->appendData("Произведён дисплей Samsung")
}
void createBox() override
{
phone->appendData("Произведён корпус Samsung")
}
void systemInstall() override
{
phone->appendData("Установлена система андройд")
}
Phone* getPhone() override
{
return Phone;
}
};
//По аналогии создадим разработчика айфонов PhoneDeveloper, реализующий интерфейс IDeveloper
class IPhoneDeveloper : public IDeveloper
{
private:
Phone* phone;
public:
//Инициализация приватного свойства phone в открытом конструкторе
IPhoneDeveloper()
{
phone = new Phone();
}
//в деструкторе класса, указать свойства phone, будет уничтожаться, освобождая память
~IPhoneDeveloper()
{
delete phone;
}
//Реализуем все методы интерфейса IDeveloper
void createDisplay() override
{
phone->appendData("Произведён дисплей Apple; ")
}
void createBox() override
{
phone->appendData("Произведён корпус Apple")
}
void systemInstall() override
{
phone->appendData("Установлена система IOS; ")
}
Phone* getPhone() override
{
return Phone;
}
};
//Для управления разработчиками, создаём класс директора
class Director
{
private:
// объявляем разработчика
IDeveloper* developer;
public:
//Инициализируем разработчика в конструкторе класса
Director (IDeveloper* dev) : developer(dev) { }
//Назначает текущего разработчика, подчиняющийся директору
void setDeveloper(IDeveloper* dev)
{
developer = dev;
}
//Директор будет иметь возможность через подчинённого разработчика смонтировать и выпустить телефон без операционной системы
Phone* MountOnlyPhone()
{
developer->createBox();
developer->createDisplay();
return developer->getPhone();
}
//или выпустить полноценный телефон с операционной системой
Phone MountFullPhone()
{
developer->createBox();
developer->createDisplay();
developer->systenInstall();
return developer->getPhone();
}
};
int main()
{
setlocale(LC_ALL, "rus");
//Создаём разработчика на андройд-платформе
IDeveloper* andrDeveloper = new AndroidDeveloper();
//Создаём директора, и в конструктор класса передаём ранее созданного разработчика
Director director(andrDeveloper);
// Собираем полноценный телефон на андройде
Phone* samsung = director.MountFullPhone();
// выводим информацию о созданном телефоне
cout << samsung->aboutPhone() << endl;
//теперь тоже самое для айфона
IDeveloper* iphoneDeveloper = new IPhoneDeveloper
director.setDeveloper(iphoneDeveloper);
//Собираем айфон без операционной системы
Phone iphone = director.MountOnlyPhone();
cout << iphone->aboutPhone() << endl;
return 0;
}
Re: Шаблоны проектирования: Учебник
Одиночка (порождающий шаблон) - гарантирует, что будет создан единственный экземпляр класса и предоставляет глобальную точку доступа к этому экземпляру
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class DatabaseHelper
{
private:
DatabaseHelper()
{
cout << "Подключение к бд" << endl;
};
static DatabaseHelper* databaseConnection;
string data;
public:
DatabaseHelper(const DatabaseHelper&) = delete;
void operator = (const DatabaseHelper&) = delete;
static DatabaseHelper* getConnection()
{
if (databaseConnection == nullptr)
databaseConnection = new DatabaseHelper();
return databaseConnection;
}
string selectData() const
{
return data;
}
void insertData(string d)
{
cout << "Новые данные: " << d << " внесены в бд" << endl;
data = d;
}
};
DatabaseHelper* DatabaseHelper::databaseConnection = nullptr;
int main()
{
setlocale(LC_ALL, "rus");
DatabaseHelper::getConnection()->insertData("123");
cout << "Выборка данных из БД: " << DatabaseHelper::getConnection()->selectData() << endl;
}
Re: Шаблоны проектирования: Учебник
Прототип (порождающий шаблон), позволяет копировать объекты, не вдаваясь в подробности их реализации
Достоинства:
Позволяет клонировать объекты, не привязываясь к их конкретным классам, уменьшая повторяющийся код для инициализации объектов
Недостатки:
Составные объекты, имеющие ссылки на другие классы клонировать сложнее
Достоинства:
Позволяет клонировать объекты, не привязываясь к их конкретным классам, уменьшая повторяющийся код для инициализации объектов
Недостатки:
Составные объекты, имеющие ссылки на другие классы клонировать сложнее
Код: Выделить всё
#include <iostream>
#include <string>
using namespeace std;
//Абстрактный класс
class Animal
{
public:
virtual void setNme(string* name) {}
virtual string getName() = 0;
virtual Animal* clone() = 0;
};
//Конкретный класс
class Sheep : public Animal
{
private:
string* name;
Sheep(const Sheep& donor)
{
this->name = donor.name;
}
public:
Sheep() {}
~Sheep()
{
delete name;
}
void setName (string* name) override
{
this->name = name;
}
string getName() override
{
return *name;
}
Sheep* clone() const
{
return new Sheep(*this);
}
};
int main()
{
setlocale(LC_ALL, "rus")
// Создадим экземпляр донора
Sheep* sheepDonor = new Sheep();
string name = "Долли";
sheepDonor->setName(&name);
//Создадим клон этого объекта
Sheep sheepClone = sheepDonor->clone();
//Значение name в объекте донора и клона будут одинаковыми
cout << sheepDonor->getName() << endl;
cout << sheepClone->getName() << endl;
return 0;
}
Re: Шаблоны проектирования: Учебник
Адаптер (структурный шаблон) - реализация на уровне объекта
Предназначен для организации функции объекта, недоступного для модификации через специально созданный интерфейс
Позволяет объектам с несовместимыми интерфейсами работать вместе.
Предназначен для организации функции объекта, недоступного для модификации через специально созданный интерфейс
Позволяет объектам с несовместимыми интерфейсами работать вместе.
Код: Выделить всё
#include <iostream>
using namespace std;
//Абстрактный класс
class Scales
{
public:
virtual float* getWight() = 0;
virtual ~Scales() {}
};
//Реализуем интерфейс
class RussianScales : public Scales
{
private:
float* currentWeight;
public:
//Приватное поле инициализируем в конструкторе класса значением
RussianScales(float* cw) : currentWeight(cw) {}
// Реализация метода гетвэйт вернёт значение карэнтвэйт
float* getWeight() override
{
return currentWeight;
}
// В переопределённом деструкторе будем удалять указатель карэнтвэй, высвобождая память
~RussianScale() override
{
delete currentWeight;
}
};
class BritishScales
{
private:
float* currentWeight;
// Инициализируем в конструкторе
BritishScales(float* cw) : currentWeight(cw) {}
// Удаляем в деструкторе
~BritishScales() { delete currentWeight; }
// Возвращаем методом гетвэйт
float* getWeight()
{
return currentWeight;
}
};
//Для согласованности классов создадим класс, реализующий интерфейс
class AdapterForBritishScales : public Scales
{
private:
BritishScales* britishScales;
float* cw;
public:
//Инициализацию полей опишем в конструкторе
AdapterForBritishScales(BritishScales* bs) : britishScales, cw(0) { }
//Удаление полей в деструкторе
~AdapterForBritishScales()
{
delete britishScales;
delete cw;
}
float* getWeight() override
{
cw = britishScales->getWeight();
*cw = *cw * 0.453;
return cw;
}
}
int main()
{
float kg = 55.0;
float lb = 55.0;
Scales* rScales = new RussianScales(&kg);
Scales* bScales = new AdapterForBritishScales(new BritishScales(&lb));
cout << *rScales->getWeight() << endl;
cout << *bScales->getWeight() << endl;
// Российские весы адаптировались к Британскому весовому номиналу
return 0;
}
Re: Шаблоны проектирования: Учебник
Адаптер (структурный шаблон) - реализация на уровне класса
Предназначен для организации использования функции объекта, недоступного для модификации через специально созданный интерфейс.
Он позволяет объектам с несовместимыми интерфейсами работать вместе
Предназначен для организации использования функции объекта, недоступного для модификации через специально созданный интерфейс.
Он позволяет объектам с несовместимыми интерфейсами работать вместе
Код: Выделить всё
#include <iostream>
using namespace std;
// Абстрактный класс
class Scales
{
public:
virtual float* getWeight() = 0;
virtual void adjust() = 0;
virtual ~Scales() {}
};
//Реализуем интерфейс, представляющий российские весы
class RussianScales : public Scales
{
private:
float* currentWeight;
public:
// Инициализируем приватное поле в конструкторе класса значением
RussianScales(float* cw) : currentWeight(cw) {}
// В переопределённом деструкторе будем удалять указатель, высвобождая память
~RussianScales() override
{
delete currentWeight;
}
float* getWeight() override
{
return currentWeight;
}
void adjust() override
{
cout << "Регулировка российских весов" << endl;
}
};
// Класс британских весов
class BritishScales
{
private:
float* currentWeight;
public:
//Инициализируем в конструкторе
BritishScales(float* cw) : currentWeight(cw) {}
//Удаляем в деструкторе
~BritishScales()
{
delete currentWeight;
}
float* getWeight()
{
return currentWeight;;
}
protected:
void adjust()
{
cout << "Регулировка британских весов";
}
};
// Для согласованности британских весов в килограммах, создадим класс адаптера для британских весов,
// реализующий интерфейс абстрактного класса весов и наследующий от базового класса британских весов
class AdapterForBritishScales : public Scales, private BritishScales
{
private:
float* cw;
public:
// Конструктор класса будет принимать в качестве аргумента измеряемый воображаемый предмет
// и передавать его в конструктор базового класса
AdapterForBritishScales(float* cw) : BritishScales(cw) {}
// Деструктор будет удалять приватный указатель
~AdapterForBritishScales()
{
delete cw;
}
// Метод гетвэйт будет возвращать полученное значение веса из вызванного соответствующего базового класса
// умноженного на разницу килограмма от фунта
float* getWeight() override
{
cw = BritishScales::getWeight();
*cw = *cw * 0.453;
return cw;
}
// в методе аджаст будет вызываться метод базового класса с некоторым дополнением
void adjust() override
{
BritishScales::adjust();
cout << " в методе регулировки adjust() адаптера" << endl;
}
};
int main()
{
setlocale(LC_ALL, "rus");
float kg = 55.0;
float lb = 55.0;
Scales* rScales = new RussianScales(&kg);
Scales* bScales = new AdapterForBritishScales(&lb);
cout << *rScales->getWeight() << endl;
cout << *bScales->getWeight() << endl;
// измерение британских весов адаптировалось к российскому весовому номиналу
return 0;
}
Re: Шаблоны проектирования: Учебник
Мост (структурный шаблон) используется, разделяя абстракцию и реализацию так, чтобы они могли изменяться независимо
шаблон мост использует инкапсуляцию (агрегирование) и может использовать наследование для разделения ответственности между классами
шаблон мост использует инкапсуляцию (агрегирование) и может использовать наследование для разделения ответственности между классами
Код: Выделить всё
#include <iostream>
using namespace std;
//создадим виртуальный интерфейс
class DataReader
{
public:
virtual void read() = 0;
};
// Реализуем интерфейс в классах, которые будут представлять имитацию чтения данных из базы данных дэйтабэйсридэр
class DataBaseReader : public DataReader
{
public:
void reader() override
{
cout << "Данные из базы данных";
}
};
// из файла
class FileReader : public DataReader
{
public:
void reader() override
{
cout << "Данные из файла";
}
};
// Абстрактный класс отправителя
class Sender
{
protected:
DataReader* reader;
public:
Sender(DataReader* dr) : reader(dr) {}
void setDataReader(DataReader* dr)
{
reader = dr;
}
virtual void send() = 0;
}
// В качестве наследника абстрактного класса создадим конкретного наследника
class EmailSender : public Sender
{
public:
//конструктор которого будет принимать объект, реализующий интерфейс датаридер и передавать его в конструктор базового класса
EmailSender(DataReader* dr) : Sender(dr) {}
void send() override
{
reader->read();
cout << "отправлены при помощи емайла" << endl;
}
};
// по аналогии создадим класс телеграмботсэнда
class TelegramBotSender : public Sender
{
public:
TelegramBotSender(DataReader* dr) : Sender(dr) {}
void send() override
{
reader->read()
cout << " отправлены при помощи телеграм бота" << endl;
}
}
int main
{
setlocale(LC_ALL, "rus");
Sender* sender = new EmailSender(new DataBaseReader());
sender->send();
sender->setDataReader(new FileReader());
sender->send();
sender = new TetegramBotSender(new DataBaseReader());
sender->send();
}
Re: Шаблоны проектирования: Учебник
структурный шаблон Компановщик, объединяющий объекты в древовидную структуру для представления иерархии. «Компоновщик» позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.
Код: Выделить всё
#include <iostream>
#include <string>
#include <vector>
using namespeace std;
class Item
{
protected:
string itemName;
string ownerName;
public:
Item(string name) : itemName(name) {}
void setOwner(string o)
{
ownerName = o;
}
virtual void add(Item* subItem) = 0;
virtual void remove(Item* subItem) = 0;
virtual void display() = 0;
};
class ClickableItem : public Item
{
public:
ClickableItem(string name) : Item(name) {}
void add(Item* subItem) override
{
throw exception();
}
void remove(Item* subItem) override
{
throw exception();
}
void display() override
{
cout << itemName << endl;
}
};
class DropDownItem : public Item
{
private:
vector<Item*> children;
public:
DropDownItem(string name) : Item(name) {}
void add(Item* subItem) override
{
subItem->setOwner(this->itemName);
children.push_back(subItem);
}
void remove(Item* subItem) override
{
children.erase(
std::remove(children.begin(), children.end(), subItem),
children.end()
);
}
void display() override
{
for (const auto& child : children)
{
if(ownerName != "")
cout << ownerName << itemName;
child->display();
}
}
};
int main()
{
setlocale(LC_ALL, "rus");
Item* file = new DropDownItem("Файл->");
Item* create = new DropDownItem("Создать->");
Item* open = new DropDownItem("Открыть->");
Item* exit = new ClickableItem("Выход");
file->add(create);
file->add(open);
file->add(exit);
Item* project = new ClickableItem("Проект...");
Item* repository = new ClickableItem("Репозиторий...");
create->add(project);
create->add(repository);
Item* solution = new ClickableItem("Решение...");
Item* folder = new ClickableItem("Папка...");
open->add(solution);
open->add(folder);
file->display();
cout << endl;
file->remove(create);
file->display();
return 0;
}
Re: Шаблоны проектирования: Учебник
Декоратор (структурный шаблон) предназначен для динамического подключения объекту дополнительного поведения
Код: Выделить всё
#include <iostream>
using namespace std;
// Создадим интерфейс процессор
class Processor
{
public:
//в котором объявим виртуальный метод процесс
virtual void process() = 0;
};
// Создадим класс трансмитеррер, реализующий интерфейс процессор
// данный класс будет выступать передатчиком данных
class Transmitter : public Processor
{
//в нём создадим закрытое свойство дэйта
private:
string data;
// значение которому мы присвоим переданным данным в конструктор класса
public:
Transmitter(string d) : data(d) {}
// реализуем метод процесс
void process() override
{
cout << "Данные " << data << " переданы по каналу связи" << endl;
}
};
// Создадим декоратор, т.е. обёртку реализующий интерфейс процессор
class Shell : public Processor
{
// в нём будет защищённое свойство процессор, которое проинициализируется в конструкторе класса
protected:
Processor* processor;
public:
Shell(Processor* pr) : processor(pr) {}
void process() override
{
// реализуем свойство процессор, как поле одноимённого метода процесс
processor->process();
}
};
class HammingCoder : public Shell
{
public:
// в конструктор класса будет передан объект, реализующий интерфейс процессор,
// который будет так же передан в конструктор базового класса
HammingCoder(Processor* pr) : Shell(pr) {}
// переопределим виртуальный метод процесс
void process() override
{
cout << "Наложен помехоустойчивый код Хамминга->";
processor->process();
}
}
// по аналогии создадим класс энкриптор, наследуемый от класса шэлл
// данный класс будет выступать в качестве устройства шифрования, передаваемых данных
class Encryptor : public Shell
{
public:
// в конструктор класса будет передан объект, реализующий интерфейс процессор,
// который будет так же передан в конструктор базового класса
Encryptor(Processor* pr) : Shell(pr) {}
// переопределим виртуальный метод процесс
void process() override
{
cout << "Шифрование данных->";
processor->process();
}
};
int main()
{
setlocale(LC_ALL, "rus");
// Применение шаблона Декоратор:
//Создадим экземпляр передатчика, передав в конструктор некоторые данные
Processor* transmitter = new Transmitter("12345");
// процесс
transmitter->process();
cout << endl;
//Создадим экземпляр помехоусточивого устройства кодированя данных
// в качестве аргумента, в конструктор, передадим ранее созданный передатчик
Shell* hammingCoder = HammingCoder(transmitter);
hammingCoder->process();
cout << endl;
//и наконец создадим устройство шифрования данных, передав в конструктор класса экземпляр помехоустойчивого кодера
Shell* encoder = new Encryptor(hammingCoder);
encoder->process();
cout << endl;
}
Re: Шаблоны проектирования: Учебник
Структурный шаблон фасад, позволяющий скрыть сложность системы путём сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.
Код: Выделить всё
#include <iostream>
using namespace std;
class ProviderCommunication
{
public:
void receive()
{
cout << "Получение продукции" << endl;
}
void payment()
{
cout << "Оплата поставщику с удержанием комиссии за продажу продукции" << endl;
}
};
class Site
{
public:
void placement()
{
cout << "Размещение на сайте" << endl;
}
void del()
{
cout << "Удаление с сайта" << endl;
}
};
class MarketPlace()
{
private:
ProviderCommunication providerCom
Site site;
Database database;
public:
void productReceipt()
{
providerCom.recelve();
site.placement();
database.insert();
}
void productRelease()
{
providerCom.payment();
site.del();
database.del();
}
};
int main()
{
setlocale(LC_ALL, "rus");
MarketPlace marketPlace;
marketPlase.productReceipt();
cout << "____________________________" << endl;
marketPlace.productRelease();
}
Re: Шаблоны проектирования: Учебник
структурный шаблон проектирования программ «Легковес», который позволяет вместить бóльшее количество объектов в отведённую оперативную память.
Код: Выделить всё
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
struct Shared
{
string company;
string position;
Shared(const string& company_, const& position)
: company(company_), position(position_) {}
};
struct Unicue
{
string passpotr;
string name;
Unicue(const string& name_, const string& passport_)
: name(name_), passpotr(passport_) {}
};
class Flywelght
{
private:
Shared* shared;
public:
Flywelght(const Shared* shared_) : shared(new Shared(*shared_)) { }
Flywelght(const Flywelght& other) : shared(new Shared(*other.shared_)) { }
~Flywelght()
{
delete shared;
}
void Process(const Unicue* unicue) const
{
cout << "Отображаются новые данные: общие - " << shared->company << "_" << shared->position << " и уникальное " << unique.name << "_" << unique.passpotr << ")." << endl;
}
};
class FlywelghtFactory
{
private:
unordered_map<string,Flywelght> flywelght;
string GetKey(const Shared& shared) const
{
return shared.company + "_" + shared.position;
}
public:
FlywelghtFactory(initializer_list<Shared> shareds)
{
for (const Shared& shared : shareds)
{
this->flywelght.insert(make_pair<string, Flywelght>(this->GetKey(shared), Flywelght(&shared)));
}
}
Flywelght GetFlywelght(const Share& shared)
{
string key = this->GetKey(shared);
if(this->flywelght.find(key) == this->Flywelght.end())
{
cout << "Фабрика легковесов: Общий объект по ключу " << key << " не найден. Создаём новый" << endl;
this->flywelght.insert(make_pair(key, Flywelght(&shared)));
}
else
{
cout << "Фабрика легковесов: извлекаем данные из имеющихся записей по ключу " << key << "." << endl;
}
return this->flywelght.st(key);
}
void ListFlywelght() const
{
size_t count = this->flywelght.size();
cout << endl << "Фабрика легковесов: всего " << count << "записей:" << endl;
for(pair<string, Flywelght> pair : this->flywelght)
{
cout << pair.first << endl;
}
}
};
void AddSpecialistDatabase(FlywelghtFactory& ff, const string& company, const string& position,
const string& name, const string& passport)
{
cout << endl;
const Flywelght& flywelght = ff.GetFlywelght({ company, position });
flywelght.Process({ name passport });
}
int main()
{
setlocale(LC_ALL, "rus");
FlywelghtFactory* factory = new FlywelghtFactory({
{"Microsoft", "Управляющий"},
{"Google", "Android-разработчик"},
{"Google", "Web-разработчик"},
{"Apple", "IPhone-разработчик"}
});
factory->ListFlywelght();
AddSpecialistDatabase(*factory,
"Google",
"Web-разработчик",
"Борис",
"AM-17234332"
);
AddSpecialistDatabase(*factory,
"Apple",
"Управляющий",
"Александр",
"DE-2211032"
);
factory->ListFlywelght();
delete factory;
}
Re: Шаблоны проектирования: Учебник
структурный шаблон проектирования программ «Заместитель (proxy) », представляющий объект, который контролирует доступ к другому объекту, перехватывая все вызовы к нему. Положительным моментом использования паттерна в клиент-серверном приложении является то, что в нем применяется кэширование ранее полученных данных и тем самым снижается количество запросов к серверу.
Код: Выделить всё
#include <iostream>
#include <string>
#include <map>
using namespace std;
class ISite
{
public:
virtual string getPage(int num) = 0;
virtual ~ISite() {}
};
class Site : public ISite
{
public:
string getPage(int num) override
{
string page = "Эта страница сайта " + to_string(num);
return page;
}
};
class SiteProxy : public ISite
{
private:
ISite* site;
map<int, string> cache;
public:
SiteProxy(ISite* site) : site(site) { }
~SiteProxy() { delete site; }
string getPage(int num) override
{
string page;
if(cache.find(num) == cache.end())
{
page = site->getPage(num);
cache[num] = page;
}
else
{
page = cache[num];
page.insert(0, "из кэша: ");
}
return page;
}
}
int main()
{
setlocale(LC_ALL, "rus");
ISite* mySite = new SiteProxy(new Site());
cout << mySite->getPage(1) << endl;
cout << mySite->getPage(2) << endl;
cout << mySite->getPage(3) << endl;
cout << mySite->getPage(2) << endl;
}
Re: Шаблоны проектирования: Учебник
«Цепочка обязанностей», который предназначенный для организации в системе уровней ответственности.
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class IWorker
{
public:
virtual IWorker* setNextWorker(IWorker* worker) = 0;
virtual string execute(string command) = 0;
};
class AbstractWorker : public IWorker
{
private:
IWorker* nextWorker;
public:
AbstractWorker() : nextWorker(nullptr) {}
IWorker* nextWorker;(IWorker* worker) override
{
nextWorker = worker;
return worker;
}
string execute(string command) override
{
if (nextWorker)
return nextWorker->execute(command);
return {};
}
};
class Designer : public AbstractWorker
{
public:
string execute(string command) override
{
if (command == "спроектировать дом")
return "Проектировщик выполнил команду: " + command;
else
return AbstractWorker::execute(command);
}
};
class Carpenters : public AbstractWorker
{
public:
string execute(string command) override
{
if (command == "класть кирпич")
return "Плотник выполнил команду: " + command;
else
return AbstractWorker::execute(command);
}
};
class FinishingWorker : public AbstractWorker
{
public:
string execute(string command) override
{
if (command == "Клеить обои")
return "Рабочий внутренней отделки выполнил команду: " + command;
else
return AbstractWorker::execute(command);
}
};
void giveCommand(IWorker worker, string command)
{
string str = worker->execute(command);
if (str.empty())
{
cout << command << " - никто не умеет делать" << endl;
}
else
{
cout << str << endl;
}
}
int main()
{
setlocale(LC_ALL, "rus");
Designer* designer = new Designer();
Carpenters* carpenters = new Carpenters();
FinishingWorker* finishingWorker = new FinishingWorker();
designer->setNextWorker(carpenters)->setNextWorker(finishingWorker);
giveCommand(designer, "спроектировать дом");
giveCommand(designer, "класть кирпич");
giveCommand(designer, "клеить обои");
giveCommand(designer, "провести проводку");
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Команда», в котором объект используется для инкапсуляции всей информации, необходимой для выполнения действия или вызова события в более позднее время. Эта информация включает в себя имя метода, объект, который является владельцем метода и значения параметров метода.
Код: Выделить всё
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
class ICommand
{
public:
virtual void positive() = 0;
virtual void negative() = 0;
};
class Conveyor
{
public:
void on()
{
cout << "Конвеер запущен" << endl;
}
void off()
{
cout << "Конвеер остановлен" << endl;
}
void speedIncrease()
{
cout << "Увеличина скорость конвейера" << endl;
}
void speedDecrease()
{
cout << "Снижена скорость конвейера" << endl;
}
};
class ConveyorWorkCommand : public ICommand
{
private:
Conveyor* conveyor;
public:
ConveyorWorkCommand(Conveyor* _conveyor) : conveyor(_conveyor) {}
void positive() override
{
conveyor->on();
}
void negative() override
{
conveyor->off();
}
};
class ConveyorAdjustCommand : public ICommand
{
private:
Conveyor* conveyor;
private:
ConveyorAdjustCommand(Conveyor* _conveyor) : conveyor(_conveyor) {}
void positive() override
{
conveyor->speedIncrease();
}
void negative() override
{
conveyor->speedDecrease();
}
};
class Multipult
{
private:
vector<ICommand*> commands;
stack<ICommand*> history;
public:
Multipult()
{
commands.resize(2);
}
void setCommand(int button, ICommand* command)
{
commands[button] = command;
}
void pressOn(int button)
{
commands[button]->positive();
history.push(commands[button])
}
void pressCancel()
{
if (!history.empty())
{
history.top()->negative();
history.pop();
}
}
};
int main()
{
setlocale(LC_ALL, "rus");
Conveyor* conveyor = new Conveyor();
Multipult* multipult = new Multipult();
multipult->setCommand(0, new ConveyorWorkCommand(conveyor));
multipult->setCommand(1, new ConveyorAdjustCommand(conveyor));
multipult->pressOn(0);
multipult->pressOn(1);
multipult->pressCancel();
multipult->pressCancel();
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Итератор», который представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из агрегированных объектов.
Код: Выделить всё
#include <iostream>
using namespace std;
class DataStack
{
private:
int items[10];
int length;
public:
friend class StackIterator;
DataStack()
{
length = -1;
}
void push(int value)
{
items[++length] = value;
}
void pop()
{
return items[length--];
}
};
class StackIterator
{
private:
const DataStack& stack;
int index;
public:
StackIterator(const DataStack& st) : stack(st)
{
index = 0;
}
void operator++()
{
index++;
}
int operator*()
{
return stack.items[index];
}
bool operator()()
{
return index !=stack.length + 1;
}
};
bool operator==(const DataStack& s1, const DataStack& s2)
{
StackIterator it1(s1), it2(s2);
for(; it1(); ++it1, ++it2)
{
if (*it1 != *it2) break;
}
return !it1() && !it2();
}
int main()
{
DataStack stack1;
for (int i = 1; i < 5; i++)
stack1.push(i);
DataStack stack2(stack1);
cout << boolalpha << (stack1 == stack2) << endl;
stack1.push(10);
cout << boolalpha << (stack1 == stack2) << endl;
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Посредник» (Mediator), который позволяет уменьшить связанность множества классов между собой, благодаря перемещению этих связей в один класс-посредник.
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class Employee;
class Mediator
{
public:
virtual void Notify(Employee* emp, string msg) = 0;
}
class Employee
{
protected:
Mediator* mediator;
public:
Employee(Mediator* med = nullptr) : mediator(med) {}
void setMediator(Mediator* med)
{
mediator = med;
}
virtual ~Employee() {}
};
class Designer : public Employee
{
private:
bool isWorking;
public:
Designer(Mediator* med = nullptr) : Employee(med) {}
void executerWork()
{
cout << "<-Дизайнер в работе" << endl;
mediator->Notify(this, "дизайнер проектирует...");
}
void setWork(bool state)
{
isWorking = state;
if(state)
cout << "<-Дизайнер освобождён от работы" << endl;
else
cout << "<-Дизайнер занят" << endl;
}
};
class Director : public Employee
{
private:
string text;
public:
Director(Mediator* med = nullptr) : Employee(med) {}
void giveCommand(string txt)
{
text = txt;
if(text.empty())
cout << "->Директор знает, что дизайнер уже работает" << endl;
else
cout << "->Директор дал команду: " << text << endl;
mediator->Notify(this, text);
}
};
class Controller : public Mediator
{
private:
Designer* designer;
Director* director;
public:
Controller(Designer* des, Director* dir)
{
designer = des;
director = dir;
designer->setMediator(this);
director->setMediator(this);
}
void Notify(Employee* emp, string msg) override
{
if (auto dir = dynamic_cast<Director*>(emp))
{
if (msg.empty())
{
designer->setWork(false);
}
else
{
designer->setWork(true);
}
}
if (auto des = synamic_cast<Designer*>(emp))
{
if (msg == "дизайнер проектирует...")
{
director->giveCommand("");
}
}
}
};
int main()
{
setlocale(LC_ALL, "rus");
Designer* designer = new Designer();
Director* director = new Director();
Controller* mediator = new Controller(designer, director);
director->giveCommand("Проектировать");
cout << endl;
designer->executeWork();
delete designer;
delete director;
delete mediator;
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Снимок» (Memento), который позволяет сохранять и восстанавливать прошлые состояния объектов, не раскрывая подробностей их реализации.
Положительным моментом использования паттерна является, то что он не нарушает инкапсуляции исходного объекта и упрощает его структуру. Недостатком может быть большое количество памяти, выделяемое при частом создании снимка состояния.
Положительным моментом использования паттерна является, то что он не нарушает инкапсуляции исходного объекта и упрощает его структуру. Недостатком может быть большое количество памяти, выделяемое при частом создании снимка состояния.
Код: Выделить всё
#include <iostream>
#include <string>
#include <stack>
using namespace std;
class Memento
{
public:
virtual int getDollars() = 0;
virtual int getEuro() = 0;
virtual ~Memento() {}
};
class ExchangeMemento : public Memento
{
private:
int dollars;
int euro;
public:
ExchangeMemento(int d, int e) : dollars(d), euro(e) {}
int getDollars() override
{
return dollars;
}
int getEuro() override
{
return euro;
}
};
class Exchange
{
private:
int dollars;
int euro;
public:
Exchange(int d, int e) : dollars(d), euro(e) {}
void getDollars()
{
cout << "Долларов: " << dollars << endl;
}
void getEuro()
{
cout << "Евро: " << euro << endl;
}
void sell()
{
dollars ? --dollars : 0;
}
void buy()
{
++euro;
}
ExchangeMemento* save()
{
return new ExchangeMemento(dollars, euro);
}
void restore(Memento* exchangeMemento)
{
dollars = exchangeMemento->getDollars();
euro = exchangeMemento->getEuro;
delete exchangeMemento;
}
};
class Memory
{
private:
stack<Memento*> history;
Exchange* exchange;
public:
Memory(Exchange* ex) : exchange(ex) {}
void backup()
{
history.push(exchange->save());
}
void undo()
{
if(history.empty() return;
exchange->restore(history.top());
history.pop();
}
};
int main()
{
setlocale(LC_ALL, "rus");
Exchange* exchange = new Exchange(10, 10);
Memory* memory = new Memory(exchange);
exchange->getDollars();
exchange->getEuro();
cout << "---- Продажа доллара, покупка евро ----" << endl;
exchange->sell();
exchange->buy();
exchange->getDollars();
exchange->getEuro();
cout << "---- Сохранение состояния ----" << endl;
memory->backup();
cout << "---- Продажа доллара, покупка евро ----" << endl;
exchange->sell();
exchange->buy();
exchange->getDollars();
exchange->getEuro();
cout << "---- Восстановление состояния ----" << endl;
memory->undo();
exchange->getDollars();
exchange->getEuro();
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Наблюдатель» (Observer), который позволяет одним объектам следить и реагировать на события, происходящие в других объектах.
Код: Выделить всё
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class IObserver
{
public:
virtual void update(double p) = 0;
};
class IObservable
{
public:
virtual void addObserver(IObserver* o) = 0;
virtual void removeObserver(IObserver* o) = 0;
virtual void notify() = 0;
virtual ~IObservable() {}
};
class Product : public IObservable
{
private:
vector<IObserver*> observers;
double price;
public:
Product(double p) : price(p) {}
void changePrice(double p)
{
price = p;
notify();
}
void addObserver(IObserver* o) override
{
observers.push_back(o);
}
void removeObserver(IObserver* o) override
{
observers.erase(remove(observers.begin(), observers.end(), o), observers.end());
}
void notify() override
{
for (auto o : observers)
{
o->update(price);
}
}
};
class Wholesaler : public IObserver
{
private:
IObservable* product;
public:
Wholeasaler(IObservable* obj) : product(obj)
{
obj->addObserver(this);
}
void update(double p) override
{
if (p < 300)
{
cout << "Оптовик закупил товар по цене" << p << endl;
product->removeObserver(this);
}
}
};
class Buyer : public IObserver
{
private:
IObservable* product;
public:
Buyer(IObservable* obj) : product(obj)
{
obj->addObserver(this);
}
void update(double p) override
{
if (p < 350)
{
cout << "Покупатель закупил товар по цене" << p << endl;
product->removeObserver(this);
}
}
};
int main()
{
setlocale(LC_ALL, "rus");
Product* product = new Product(400);
Wholesaler* wholesaler = new Wholesaler(product);
Buyer* buyer = new Buyer(product);
product->changePrice(320);
product->changePrice(280);
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Состояние» (State), который позволяет объектам менять поведение в зависимости от своего состояния. Паттерн может найти широкое применение в системах где необходимо избавиться от большого количества условных операторов.
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class TrafficLight;
class State
{
protected:
TrafficLight* trafficLight;
public:
virtual ~State() {}
void setTrafficLight(TrafficLight* tr)
{
trafficLight = tr;
}
virtual void nextState() = 0;
virtual void previousState() = 0;
};
class TrafficLight
{
private:
State* state;
public:
TrafficLight(State* st) : state(nullptr)
{
setState(st);
}
void setState(State* st)
{
if (state != nullptr) delete state;
state = st;
state->setTrafficLight(this);
}
void nextState()
{
state->nextState();
}
void previousState()
{
state->previousState();
}
};
class GreenState : public State
{
public:
void nextState() override;
void previousState() override
{
cout << "Зелёный цвет" << endl;
}
};
class YellowState : public State
{
public:
void nextState() override;
void previousState() override
{
cout << "Из жёлтого в зелёный цвет" << endl;
trafficLight->setState(new GreenState());
}
};
void GreenState::nextState()
{
cout << "Из зелёного в жёлтый цвет" << endl;
trafficLight->setState(new YellowState());
}
class RedState : public State
{
public:
void nextState() override
{
cout << "Красный цвет" << endl;
}
void prevousState() override
{
cout << "Из красного в жёлтый цвет" << endl;
trafficLight->setState(new YellowState());
}
};
void YellowState::nextState()
{
cout << "Из жёлтого в красный" << endl;
trafficLight->setState(new RedState());
}
int main()
{
setlocale(LC_ALL, "rus");
TrafficLight* trafficLight = new TrafficLight(new YellowState());
trafficLight->nextState();
trafficLight->nextState();
trafficLight->previousState();
trafficLight->previousState();
trafficLight->previousState();
delete trafficLight;
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Стратегия», который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс. Положительными моментами является то, что паттерн изолирует код алгоритмов от остальных классов, алгоритмы можно быстро заменять, во время выполнения программы.
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class Reader
{
public:
virtual ~Reader() {}
virtual void parce(string& url) = 0;
};
class ResourceReader
{
private:
Reader* reader;
public:
ResourceReader(Reader* r) : reader(r) {};
~ResourceReader() { delete reader; }
void setStrategy(Reader* r)
{
if (reader != nullptr) delete reader;
reader = r;
}
void read(string& url)
{
reader->parce(url);
}
};
class NewsSiteReader : public Reader
{
public:
void parce(string& url) override
{
cout << "Парсинг с новостного сайта: " << url << endl;
}
};
class SocialNetworkReader : public Reader
{
public:
void parce(string& url) override
{
cout << "Парсинг ленты новостей социальной сети: " << url << endl;
}
};
class TelegramChannelReader : public Reader
{
public:
void parce(string& url) override
{
cout << "Парсинг канала мессенджера Тлеграм: " << url << endl;
}
};
int main()
{
setlocale(LC_ALL, "rus");
ResourceReader* resourceReader = new ResourceReader(new NewsSiteReader());
string url = "https://news.com";
resourceReader->read(url);
url = "https://facebook.com";
resourceReader->setStrategy(new SocialNetworkReader());
resourceReader->read(url);
url = "@news_channel_telegram";
resourceReader->setStrategy(new TelegramChannelReader());
resourceReader->read(url);
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Шаблонный метод» (Template method), определяющий основу алгоритма и позволяющий наследникам переопределять некоторые шаги алгоритма, не изменяя его структуру в целом. Преимуществом паттерна является то, что он облегчает повторное использование кода.
Код: Выделить всё
#include <iostream>
using namespace std;
class Transmitter
{
protected:
virtual void voiceRecord()
{
cout << "Запись фрагмента речи" << endl;
};
virtual void simpling() {};
virtual void digitization() {};
virtual void modulation() = 0;
virtual void transmission()
{
cout << "Передача сигнала по радиоканалу" << endl;
};
public:
void processStart()
{
voiceRecord();
simpling();
digitization();
modulation();
transmission();
}
virtual Transmitter() {}
};
class AnalogTransmitter : public Transmitter
{
public:
void modulation() override
{
cout << "Модуляция аналогового сигнала" << endl;
}
};
class DigitTransmitter : public Transmitter
{
public:
void simpling() override
{
cout << "Дискретизация записанного фрагмента" << endl;
}
void digitization() override
{
cout << "Оцифровка" << endl;
}
void modulation() override
{
cout << "Модуляция цифрового сигнала" << endl;
}
};
int main()
{
setlocale(LC_ALL, "rus");
Transmitter* analogTransmitter = new AnalogTransmitter();
analogTransmitter->processStart();
cout << endl;
Transmitter* digitTransmitter = new DigitTransmitter();
digitTransmitter->processStart();
delete analogTransmitter;
delete digitTransmitter;
}
Re: Шаблоны проектирования: Учебник
поведенческий шаблон проектирования программ «Посетитель» (Visitor), позволяющий добавлять в программу новые операции, не изменяя классы объектов, над которыми эти операции могут выполняться. Преимуществом паттерна является то, что он объединяет родственный операции в одном классе, упрощает добавление операций, работающих со сложными структурами объектов. Отрицательным моментом является возможное нарушение инкапсуляции элементов.
Код: Выделить всё
#include <iostream>
#include <string>
using namespace std;
class Zoo;
class Cinema;
class Circus;
class IVisitor
{
public:
virtual void visit(Zoo& ref) = 0;
virtual void visit(Cinema& ref) = 0;
virtual void visit(Circus& ref) = 0;
virtual ~IVisitor() = default;
};
class Place
{
public:
virtual void accept(IVisitor& v) = 0;
virtual ~Place() = default;
};
class Zoo : public Place
{
public:
void accept(IVisitor& v) override
{
v.visit(*this);
}
};
class Cinema : public Place
{
public:
void accept(IVisitor& v) override
{
v.visit(*this);
}
};
class Circus : public Place
{
public:
void accept(IVisitor& v) override
{
v.visit(*this);
}
};
class HolidayMaker : public IVisitor
{
public:
string value;
public:
void visit(Zoo& ref) override
{
value = "Слон в зоопарке";
}
void visit(Cinema& ref) override
{
value = "Кино - Властелин колец";
}
void visit(Circus& ref) override
{
value = "Клоун в цирке";
}
};
int main()
{
setlocale(LC_ALL, "rus");
Zoo zoo;
Cinema cinema;
Circus circus;
Place* places[] = { &zoo, &cinema, &circus};
for (auto place : places)
{
HolidayMaker visitor;
place->accept(visitor);
cout << visitor.value << endl;
}
}