Страница 1 из 1

Шаблоны проектирования: Учебник

Добавлено: 25 авг 2024, 22:16
ya
Швец Александр - Погружение в паттерны проектирования - 2021
Изображение

Re: Шаблоны проектирования: Учебник

Добавлено: 25 авг 2024, 22:52
ya
Миллетт С., Тьюн Н. - Предметно-ориентированное проектирование. Паттерны, принципы и методы (Для профессионалов) - 2017

Re: Шаблоны проектирования: Учебник

Добавлено: 25 авг 2024, 23:10
ya
Могелашвили - Паттерны проектирования

https://e19.hardprivate.com/Mogeashvilly_PatternyProektirovaniya.zip

Re: Шаблоны проектирования: Учебник

Добавлено: 02 сен 2024, 21:56
ya
Шаблон проектирования Фабричный метод (порождающий шаблон)

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 08 сен 2024, 19:33
ya
Абстрактная фабрика (порождающий шаблон)
Применяется: когда программа должна быть независима от процессов и типов создаваемых объектов, а так же когда необходимо создать семейство или группы взаимосвязанных объектов.

Достоинства:
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: Шаблоны проектирования: Учебник

Добавлено: 08 сен 2024, 20:51
ya
Строитель (пораждающий шаблон) - предоставляет способ создания составного объекта

отделяет конструирование сложного объекта от его представления, так что в результате одного и того же конструирования могут получаться разные представления

Достоинства:
позволяет изменять внутреннее представление продукта
изолирует код, реализующий конструирование и представление
даёт более тонкий контроль над процессом конструирования
алгоритм создания не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 09 сен 2024, 08:18
ya
Одиночка (порождающий шаблон) - гарантирует, что будет создан единственный экземпляр класса и предоставляет глобальную точку доступа к этому экземпляру

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 09 сен 2024, 21:06
ya
Прототип (порождающий шаблон), позволяет копировать объекты, не вдаваясь в подробности их реализации

Достоинства:
Позволяет клонировать объекты, не привязываясь к их конкретным классам, уменьшая повторяющийся код для инициализации объектов

Недостатки:
Составные объекты, имеющие ссылки на другие классы клонировать сложнее

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 09 сен 2024, 21:46
ya
Адаптер (структурный шаблон) - реализация на уровне объекта

Предназначен для организации функции объекта, недоступного для модификации через специально созданный интерфейс
Позволяет объектам с несовместимыми интерфейсами работать вместе.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 09 сен 2024, 22:48
ya
Адаптер (структурный шаблон) - реализация на уровне класса

Предназначен для организации использования функции объекта, недоступного для модификации через специально созданный интерфейс.
Он позволяет объектам с несовместимыми интерфейсами работать вместе

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 09 сен 2024, 23:40
ya
Мост (структурный шаблон) используется, разделяя абстракцию и реализацию так, чтобы они могли изменяться независимо

шаблон мост использует инкапсуляцию (агрегирование) и может использовать наследование для разделения ответственности между классами

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 10 сен 2024, 15:53
ya
структурный шаблон Компановщик, объединяющий объекты в древовидную структуру для представления иерархии. «Компоновщик» позволяет клиентам обращаться к отдельным объектам и к группам объектов одинаково.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 15 сен 2024, 20:03
ya
Декоратор (структурный шаблон) предназначен для динамического подключения объекту дополнительного поведения

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 14 окт 2024, 14:59
ya
Структурный шаблон фасад, позволяющий скрыть сложность системы путём сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 14 окт 2024, 16:49
ya
структурный шаблон проектирования программ «Легковес», который позволяет вместить бóльшее количество объектов в отведённую оперативную память.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 14 окт 2024, 17:14
ya
структурный шаблон проектирования программ «Заместитель (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: Шаблоны проектирования: Учебник

Добавлено: 23 окт 2024, 16:44
ya
«Цепочка обязанностей», который предназначенный для организации в системе уровней ответственности.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 24 окт 2024, 18:27
ya
поведенческий шаблон проектирования программ «Команда», в котором объект используется для инкапсуляции всей информации, необходимой для выполнения действия или вызова события в более позднее время. Эта информация включает в себя имя метода, объект, который является владельцем метода и значения параметров метода.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 25 окт 2024, 10:54
ya
поведенческий шаблон проектирования программ «Итератор», который представляет собой объект, позволяющий получить последовательный доступ к элементам объекта-агрегата без использования описаний каждого из агрегированных объектов.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 30 окт 2024, 15:47
ya
поведенческий шаблон проектирования программ «Посредник» (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: Шаблоны проектирования: Учебник

Добавлено: 31 окт 2024, 13:10
ya
поведенческий шаблон проектирования программ «Снимок» (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: Шаблоны проектирования: Учебник

Добавлено: 31 окт 2024, 15:22
ya
поведенческий шаблон проектирования программ «Наблюдатель» (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: Шаблоны проектирования: Учебник

Добавлено: 01 ноя 2024, 10:50
ya
поведенческий шаблон проектирования программ «Состояние» (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: Шаблоны проектирования: Учебник

Добавлено: 01 ноя 2024, 12:01
ya
поведенческий шаблон проектирования программ «Стратегия», который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс. Положительными моментами является то, что паттерн изолирует код алгоритмов от остальных классов, алгоритмы можно быстро заменять, во время выполнения программы.

Код: Выделить всё

#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: Шаблоны проектирования: Учебник

Добавлено: 01 ноя 2024, 12:27
ya
поведенческий шаблон проектирования программ «Шаблонный метод» (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: Шаблоны проектирования: Учебник

Добавлено: 01 ноя 2024, 17:23
ya
поведенческий шаблон проектирования программ «Посетитель» (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;
	}
}