Professional Documents
Culture Documents
DP урок 01 ua
DP урок 01 ua
DP урок 01 ua
Породжуючі
патерни
проєктування
Зміст
1. Вступ у патерни проєктування . . . . . . . . . . . . . . . . . . 4
1.1. Про тенденції розвитку патернів
у програмуванні. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2. Причини виникнення патернів
проєктування. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3. Поняття патерну проєктування. . . . . . . . . . . . . . . 7
1.4. Практичне застосування патернів
проєктування. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.5. Класифікація патернів. . . . . . . . . . . . . . . . . . . . . . 11
2. Короткий вступ у UML. . . . . . . . . . . . . . . . . . . . . . . . . 14
2.1. Діаграма класів. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.2. Діаграма об᾿єктів. . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2
Зміст
3. Породжуючі патерни . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.1. Abstract Factory. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2. Builder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.3. Factory Method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.4. Prototype. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.5. Singleton. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
3.6. Аналіз і порівняння породжуючих патернів. . . 80
4. Домашнє завдання . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5. Використані інформаційні джерела. . . . . . . . . . . . . 83
3
Урок №1
1. Вступ у патерни
проєктування
4
1. Вступ у патерни проєктування
5
Урок №1
6
1. Вступ у патерни проєктування
7
Урок №1
8
1. Вступ у патерни проєктування
9
Урок №1
10
1. Вступ у патерни проєктування
11
Урок №1
12
1. Вступ у патерни проєктування
13
Урок №1
14
2. Короткий вступ у UML
1) назва класу;
2) атрибути (поля, члени даних) класу;
3) операції (методи, функції-члени) класу.
Секції 2 і 3 у зображенні класу можуть бути відсутніми.
Загалом, атрибут класу позначається так
[visibility] name [multiplicity] [: type]
[= initial value] [{property}]
15
Урок №1
16
2. Короткий вступ у UML
17
Урок №1
18
2. Короткий вступ у UML
19
Урок №1
20
2. Короткий вступ у UML
21
Урок №1
3. Породжуючі патерни
Породжуючі патерни проєктування абстрагують
процес інстанціювання. Вони допомагають зробити си-
стему незалежною від способу створення, композиції та
уявлення об’єктів. Патерни такої категорії дозволяють
відповісти на запитання: хто, коли і як створює об’єкти
в системі. [GoF95]
3.1. Abstract Factory
3.1.1. Назва патерну
Abstract Factory / Абстрактна фабрика
Також відомий під назвою: Toolkit / Інструментарій
Описаний у праці [GoF95].
3.1.2. Мета патерну
Надає інтерфейс створення сімейства взаємопов᾿я-
заних і взаємозалежних об᾿єктів, не специфікуючи кон-
кретні класи, об᾿єкти яких створюватимуться. [GoF95]
3.1.3. Патерн слід використовувати коли:
■ система має залежати від того, як у ній створюються
і компонуються об’єкти;
■ об’єкти сімейства мають використовуватися разом;
■ система має конфігуруватися одним із сімейств об’єктів;
■ потрібно надати інтерфейс бібліотеки, не розкриваючи
її внутрішньої реалізації.
22
3. Породжуючі патерни
23
Урок №1
Абстрактні складові
interface, АбстрактнийДвигун
ФабрикаСкладових
АбстрактнеКолесо
+ СтворитиДвигун() : АбстрактнийДвигун
+ СтворитиКолесо() : АбстрактнеКолесо
+ СтворитиКузов() : АбстрактнийКузов АбстрактнийКузов
+ СтворитиКоробкуПередач() : Абстрактна-
КоробкаПередач
АбстрактнаКоробкаПередач
+ СтворитиБензобак() : АбстрактнийБензобак
АбстрактнийБензобак
Тюнер Автомобіль
+ СтворитиДвигун() : АбстрактнийДвигун
ТюнерКолесо
+ СтворитиКолесо() : АбстрактнеКолесо
+ СтворитиКузов() : АбстрактнийКузов
+ СтворитиКоробкуПередач() : Абстрактна- ТюнерКузов
КоробкаПередач
+ СтворитиБензобак() : АбстрактнийБензобак
ТюнерКоробкаПередач
ТюнерБензобак
Экзотик-автомобиль
ФабрикаЭкзотик ЕкзотикДвигун
+ СтворитиДвигун() : АбстрактнийДвигун
ЕкзотикКолесо
+ СтворитиКолесо() : АбстрактнеКолесо
+ СтворитиКузов() : АбстрактнийКузов
+ СтворитиКоробкуПередач() : Абстрактна- ЕкзотикКузов
КоробкаПередач
+ СтворитиБензобак() : АбстрактнийБензобак
ЕкзотикКоробкаПередач
ЕкзотикБензобак
24
3. Породжуючі патерни
25
Урок №1
Учасники патерну:
■ AbstractFactory — абстрактна фабрика. Представлений
загальним інтерфейсом створення сімейства продуктів.
■ ConcreteFactory — конкретна фабрика. Реалізує інтер-
фейс AbstractFactory і створює сімейство конкретних
продуктів.
■ AbstractProduct — абстрактний продукт. Представле-
ний інтерфейсом абстрактного продукту, посилання
на який повертають методи фабрик.
■ ConcreteProduct — конкретний продукт. Реалізує кон-
кретний тип продукту, який створюється конкретною
фабрикою.
Зв’язки між учасниками:
■ Клієнт знає лише про існування абстрактної фабрики
і абстрактних продуктів.
26
3. Породжуючі патерни
27
Урок №1
28
3. Породжуючі патерни
virtual ~PC() {
if (box)
delete box;
if (processor)
delete processor;
if (mainBoard)
delete mainBoard;
if (hdd)
delete hdd;
if (memory)
delete memory;
}
Box* GetBox() {
return box;
}
void SetBox(Box* pBox){
box = pBox;
}
Processor* GetProcessor() {
return processor;
}
void SetProcessor(Processor* pProcessor) {
processor = pProcessor;
}
MainBoard* GetMainBoard() {
return mainBoard;
}
void SetMainBoard(MainBoard* pMainBoard) {
mainBoard = pMainBoard;
}
29
Урок №1
Hdd* GetHdd() {
return hdd;
}
void SetHdd(Hdd* pHdd) {
hdd = pHdd;
}
Memory* GetMemory() {
return memory;
}
void SetMemory(Memory* pMemory) {
memory = pMemory;
}
};
/*
* Інтерфейс фабрики по створенню конфігурації
* системного блоку персонального комп’ютера
*/
class IPCFactory {
public:
virtual Box* CreateBox() = 0;
30
3. Породжуючі патерни
/*
* Фабрика по створенню "домашньої" конфігурації
* системного блоку персонального комп’ютера
*/
class HomePcFactory : public IPCFactory {
public:
Box* CreateBox()
{
return new SilverBox();
}
Processor* CreateProcessor()
{
return new IntelProcessor();
}
MainBoard* CreateMainBoard()
{
return new MSIMainBord();
}
31
Урок №1
Hdd* CreateHdd()
{
return new SamsungHDD();
}
Memory* CreateMemory()
{
return new Ddr2Memory();
}
};
/*
* Фабрика по створенню "офісної" конфігурації
* системного блоку персонального комп’ютера
*/
class OfficePcFactory : public IPCFactory {
public:
Box* CreateBox()
{
return new BlackBox();
}
Processor* CreateProcessor()
{
return new AmdProcessor();
}
MainBoard* CreateMainBoard()
{
return new AsusMainBord();
}
32
3. Породжуючі патерни
Hdd* CreateHdd()
{
return new LGHDD();
}
Memory* CreateMemory()
{
return new DdrMemory();
}
};
// клас конфігуратор
class PcConfigurator
{
/*
* Фабрика складових персонального комп’ютера
*/
IPCFactory* pcFactory;
public:
PcConfigurator() {
pcFactory = NULL;
}
virtual ~PcConfigurator() {
if(pcFactory)
delete pcFactory;
}
33
Урок №1
IPCFactory* GetPCFactory() {
return pcFactory;
}
/*
* Метод конфігурування системного блоку
*/
void Configure(PC* pc)
{
pc->SetBox(pcFactory->CreateBox());
pc->SetMainBoard(pcFactory->CreateMainBoard());
pc->SetHdd(pcFactory->CreateHdd());
pc->SetMemory(pcFactory->CreateMemory());
pc->SetProcessor(pcFactory->CreateProcessor());
}
};
34
3. Породжуючі патерни
35
Урок №1
36
3. Породжуючі патерни
37
Урок №1
38
3. Породжуючі патерни
Конвеєр
- Технологія: ТехнологіяМоделі
ТехнологіяМоделі
+ Зібрати
технологія.ЗібратиКузов(); + ПідготуватиСалон()
технологія.ВстановитиДвигун(); + Пофарбувати()
for(i=1; i<=4; ++i){ + ЗібратиКузов()
технологія.ВстановитиКолесо(); + ВстановитиДвигун()
} + ВстановитиКолесо()
технологія.Пофарбувати;
технологія.ПідготуватиСалон();
39
Урок №1
Учасники патерну:
■ Builder (ТехнологіяМоделі) — будівельник
▷ Забезпечує інтерфейс для поетапного конструю-
вання складного об᾿єкта (продукту) з елементів.
■ ConcreteBuilder (ТехнологіяМініАвто та ін.) — кон-
кретний будівельник
▷ Реалізує етапи побудови складного об᾿єкта, визна-
чені у базовому класі Builder.
▷ Створює результат побудови (Product) і слідкує за
покроковим конструюванням.
▷ Визначає інтерфейс доступу до результату кон-
струювання.
■ Director (Конвеєр) — розпорядник
▷ Визначає загальний алгоритм конструювання, вико-
ристовуючи реалізації окремих кроків можливості
класу Builder.
40
3. Породжуючі патерни
41
Урок №1
private:
// тип літального апарату
string aircraftType;
// сховище інформації про літальний апарат
map<string, string> parts;
public:
// отримання інформації про певну частину апарату
string GetPart(const string& key) {
if (!CheckForPart(key)) {
throw "There is no such key!";
}
return parts[key];
}
42
3. Породжуючі патерни
Aircraft::Aircraft(string type)
{
aircraftType = type;
}
Aircraft::~Aircraft()
{
}
void Aircraft::Show() {
cout<<"\n====================\n";
cout<<"Aircraft Type:"<<aircraftType<<endl;
cout<<"Engine:"<<parts["engine"]<<endl;
cout<<"Wheels:"<<parts["wheels"]<<endl;
cout<<"Doors:"<<parts["doors"]<<endl;
}
43
Урок №1
protected:
Aircraft* aircraft;
public:
Aircraft* GetAircraft() {
return aircraft;
}
44
3. Породжуючі патерни
public:
void BuildFrame();
void BuildEngine();
void BuildWheels();
void BuildDoors();
void BuildWings();
};
HangGliderBuilder::HangGliderBuilder()
{
aircraft = new Aircraft("Hang Glider");
}
HangGliderBuilder::~HangGliderBuilder()
{
delete aircraft;
}
void HangGliderBuilder::BuildFrame() {
aircraft->SetPart("frame", "Hang glider frame");
}
void HangGliderBuilder::BuildEngine() {
aircraft->SetPart("engine", "no engine");
}
void HangGliderBuilder::BuildWheels() {
aircraft->SetPart("wheels", "no wheels");
}
45
Урок №1
void HangGliderBuilder::BuildDoors(){
aircraft->SetPart("doors", "no doors");
}
void HangGliderBuilder::BuildWings() {
aircraft->SetPart("wings", "1");
}
GliderBuilder::GliderBuilder()
{
aircraft = new Aircraft("Glider");
}
GliderBuilder::~GliderBuilder()
{
delete aircraft;
}
46
3. Породжуючі патерни
void GliderBuilder::BuildFrame() {
aircraft->SetPart("frame", "Glider frame");
}
void GliderBuilder::BuildEngine() {
aircraft->SetPart("engine", "no engine");
}
void GliderBuilder::BuildWheels() {
aircraft->SetPart("wheels", "1");
}
void GliderBuilder::BuildDoors() {
aircraft->SetPart("doors", "1");
}
void GliderBuilder::BuildWings() {
aircraft->SetPart("wings", "2");
}
47
Урок №1
AircraftConstructor::AircraftConstructor()
{
}
AircraftConstructor::~AircraftConstructor()
{
}
void
AircraftConstructor::Construct(AircraftBuilder*
aircraftBuilder)
{
aircraftBuilder->BuildFrame();
aircraftBuilder->BuildEngine();
aircraftBuilder->BuildWheels();
aircraftBuilder->BuildDoors();
}
#include<iostream>
#include"AircraftBuilder.h"
#include"AircraftConstructor.h"
#include"HangGliderBuilder.h"
#include"GliderBuilder.h"
int main() {
try {
AircraftBuilder* builder;
48
3. Породжуючі патерни
// створюємо дельтаплан
shop->Construct(builder);
// створюємо планер
shop->Construct(builder);
49
Урок №1
50
3. Породжуючі патерни
51
Урок №1
52
3. Породжуючі патерни
Учасники патерну:
■ Creator (АбстрактнаЗброя) — абстрактний розробник
▷ Має абстрактний метод створення екземпляра про-
дукту, тобто делегує виробництво продукту своїм
підкласам.
■ ConcreteCreator (Автомат, Дробовик) — конкретний
розробник
▷ Реалізує метод створення екземпляра продукту.
■ Product (АбстрактнаКуля) — абстрактний продукт
▷ Представлений абстрактним інтерфейсом продукту,
через який працює Creator.
■ ConcreteProduct (КуляАвтомата, КуляДробовика) —
конкретний продукт
▷ Здійснює інтерфейс абстрактного продукту.
Зв᾿язки між учасниками:
■ Creator є абстрактним методом FactoryMethod() ство-
рення екземпляра продукту, який повертає посилання
на Product.
■ Creator покладає відповідальність створення екземп-
ляра конкретного продукту на свої підкласи.
■ ConcreteCreator реалізує метод FactoryMethod(), за-
безпечуючи створення об’єкта класу ConcreteProduct.
53
Урок №1
54
3. Породжуючі патерни
/*
* Точка в тривимірному просторі.
* Використовується для визначення положення.
*/
struct Point3D {
int X;
int Y;
int Z;
};
/*
* Вектор у тривимірному просторі.
* Використовується для визначення напрямку.
*/
struct Vector3D {
int X;
int Y;
int Z;
};
/*
* Клас абстрактної кулі.
*/
class AbstractBullet
{
private:
Point3D location;
Vector3D direction;
double caliber;
public:
/*
* Поточне положення кулі
*/
55
Урок №1
Point3D GetLocation() {
return location;
}
/*
* Напрямок кулі
*/
Vector3D GetDirection() {
return direction;
}
/*
* Калібр кулі
*/
double GetCaliber() {
return caliber;
}
/*
* Початок руху кулі.
*/
void StartMovement()
{
// Реалізація початку руху
}
56
3. Породжуючі патерни
/*
* Метод ураження мети.
* Оскільки різні типи куль вражають ціль
* по-різному, то метод має реалізовуватися
* в підкласах.
*/
virtual void HitTarget(void* target) = 0;
/*
* Метод, що реалізує рух кулі.
* Оскільки різні типи куль мають різну
* траєкторію руху, то метод має реалізовуватися
* в підкласах.
*/
virtual void Movement() = 0;
};
/*
* Клас кулі для автоматичної зброї.
*/
class AutomaticBullet : public AbstractBullet
{
public:
void HitTarget(void* target){
// реалізація ураження цілі target
cout << "Hit by automatic bullet\n";
}
void Movement(){
// реалізація алгоритму руху кулі
}
};
57
Урок №1
/*
* Клас кулі для дробовика.
*/
class ShotgunBullet : public AbstractBullet
{
public:
void HitTarget(void* target){
void Movement(){
// реалізація алгоритму руху кулі
}
};
/*
* Клас абстрактної зброї
*/
class AbstractWeapon {
protected:
58
3. Породжуючі патерни
/*
* Фабричний метод створення кулі.
*/
virtual AbstractBullet* CreateBullet() = 0;
private:
Point3D location;
Vector3D direction;
double caliber;
public:
/*
* Поточне положення зброї
*/
Point3D GetLocation() {
return location;
}
/*
* Калібр зброї
*/
double GetCaliber() {
return caliber;
}
59
Урок №1
/*
* Метод, що робить постріл.
* Повертає екземпляр створеної кулі.
*/
AbstractBullet* Shoot(){
// створення об’єкта кулі за допомогою
// фабричного методу
AbstractBullet* bullet = CreateBullet();
// налаштування кулі на поточні параметри
// зброї
bullet->SetCaliber(this->GetCaliber());
bullet->SetLocation(this->GetLocation());
bullet->SetDirection(this->GetDirection());
// почати рух кулі
bullet->StartMovement();
// повернути екземпляр кулі
return bullet;
}
};
/*
* Клас автоматичної зброї.
*/
class AutomaticWeapon : public AbstractWeapon
{
public:
AutomaticWeapon(){
this->SetCaliber(20);
}
protected:
/*
* Реалізація фабричного методу.
60
3. Породжуючі патерни
/*
* Клас дробовика.
*/
class Shotgun : public AbstractWeapon
{
public:
Shotgun(){
this->SetCaliber(50);
}
protected:
/*
* Реалізація фабричного методу.
* Створює екземпляр кулі,
* специфічний для поточного типу зброї.
*/
AbstractBullet* CreateBullet()
{
return new ShotgunBullet();
}
};
61
Урок №1
62
3. Породжуючі патерни
3.4. Prototype
3.4.1. Назва патерну
Prototype/Прототип.
Описаний у праці [GoF95].
3.4.2. Мета патерну
Визначає види створюваних об᾿єктів за допомогою
екземпляра-прототипу і створює нові об᾿єкти шляхом
копіювання цього прототипу [GoF95].
63
Урок №1
64
3. Породжуючі патерни
Учасники патерну:
■ Prototype — прототип
▷ Визначає інтерфейс для самоклонування (у мові
C# для таких цілей можна використовувати стан-
дартний інтерфейс ICloneable).
■ ConcretePrototype — конкретний прототип
▷ Реалізує операцію самоклонування.
65
Урок №1
■ Client — клієнт
▷ Створює новий об’єкт, надсилаючи запит прототипу
«копіювати себе».
Зв’язки між учасниками: Клієнтський код звертаєть-
ся до прототипу «створити копію себе».
66
3. Породжуючі патерни
/*
* Це абстрактний базовий клас Device.
* Він визначає функцію Clone, яка складає
* основу патерну Prototype
*/
class Device {
private:
// назва пристрою
string name;
public:
// конструктора
Device() : Device("Unknown device") {}
Device(string dname){
SetName(dname);
67
Урок №1
// допоміжні функції
string GetName() const{
return name;
}
void SetName(string dname) {
name = dname;
}
// Суто віртуальна функція
// Вона використовуватиметься для створення копій
virtual Device* Clone() const = 0;
// відображення даних
void Show() const{
cout << "\nName is\n" << GetName() << "\n";
}
};
/*
* Конкретний нащадок пристрою клас Car
*/
class Car : public Device {
private:
// властивості машини
string manufacturer;
68
3. Породжуючі патерни
string description;
string color;
int year;
public:
// конструктора
Car():Car("No information", "No description",
"No color", 0){
SetName("Car");
}
Car(string cmanufacturer, string cdescription,
string ccolor, int cyear);
public:
// допоміжні функції
int GetYear()const{
return year;
}
string GetManufacturer()const{
return manufacturer;
}
string GetDescription()const{
return description;
}
string GetColor()const{
return manufacturer;
}
69
Урок №1
// реалізація конструктора
Car::Car(string cmanufacturer, string cdescription,
string ccolor, int cyear) {
SetName("Car");
SetManufacturer(cmanufacturer);
SetDescription(cdescription);
SetColor(ccolor);
SetYear(cyear);
}
// функція клонування
Device* Car::Clone() const{
Car* tempCar = new Car();
/* Зверніть увагу!
* При роботі з динамічною пам’яттю потрібно
* визначити конструктор копіювання, конструктор
* перенесення і перевантажити оператор =
*/
*tempCar = *this;
return tempCar;
}
70
3. Породжуючі патерни
int main() {
// Ввносимо дані
string manufacturer;
cout << endl << "Input manufacturer of car:"
<< endl;
std::getline(std::cin, manufacturer);
string description;
cout << "Input description of car:" << endl;
std::getline(std::cin, description);
string color;
cout << "Input color of car:" << endl;
std::getline(std::cin, color);
int year;
cout << "Input year of car:" << endl;
cin >> year;
71
Урок №1
// створимо об’єкт
Car c(manufacturer, description, color, year);
c.Show();
// клонуємо об’єкт
Car* copy = (Car*)c.Clone();
copy->Show();
return 0;
}
3.5. Singleton
3.5.1. Назва патерну
Singleton/Одинак.
Описаний у праці [GoF95].
72
3. Породжуючі патерни
73
Урок №1
74
3. Породжуючі патерни
Учасники патерну:
■ Singleton — одинак
▷ Забезпечує створення лише одного екземпляра са-
мого себе, посилання на який зберігається в ста-
тичній змінній uniqueInstance і глобальний доступ
до нього через статичний метод Instance().
▷ Забороняє клієнтському коду створювати власні
екземпляри, заборонивши йому доступ до свого
конструктора (конструктор одинак визначається
як захищений, або приватний).
75
Урок №1
Зв’язки:
■ Клієнтський код має можливість доступу до екземпляра
Singleton лише через його статичний метод Instance().
76
3. Породжуючі патерни
77
Урок №1
/*
* Клас журналу подій програми.
* Призначення — запис подій у спеціальний текстовий файл.
* У програмі може існувати тільки в одному екземплярі.
*/
class Logger {
private:
/* конструктор закритий, щоб не було можливості
* створювати копію об’єкта в
* обхід спеціальній функції
*/
Logger() {}
78
3. Породжуючі патерни
79
Урок №1
80
3. Породжуючі патерни
81
Урок №1
4. Домашнє завдання
82
5. Використані інформаційні джерела
5. Використані
інформаційні джерела
[GoF95] Гамма Е., Хелм Р., Джонсон Р., Вліссідес Дж. Прийоми об’єк-
тно-орієнтованого проєктування. Патерни проєктуван-
ня. — СПб: Пітєр, 2001. — 386 с.
[Grand2004] Гранд М. Шаблони проєктування у Java / М. Гранд;
Пер. з англ. С. Бєліковой. — М.: Новоє знаніє, 2004. — 559 с.
[SM2002] Стелтінг С., Маасен О. Використання шаблонів Java. Бібліо-
тека професіонала: Пер. з англ. — М.: Видавничий дім
«Вільямс», 2002. — 576 с.
[DPWiki] Шаблони проєктування (Wikipedia)
[DPOverview] Огляд патернів проєктування
83
Урок №1
Породжуючі патерни проєктування