Шаблони проектування

[ виправити ] текст може містити помилки, будь ласка перевіряйте перш ніж використовувати.

скачати

Шаблони проектування

Abstract factory (Абстрактна фабрика)

Abstract factory (Абстрактна фабрика) - шаблон проектування, що дозволяє змінювати поведінку системи, варіюючи створювані об'єкти, при цьому зберігаючи інтерфейси. Він дозволяє створювати цілі групи взаємозалежних об'єктів, які, будучи створеними однією фабрикою, реалізують загальну поведінку. Шаблон реалізується створенням абстрактного класу Factory, який представляє собою інтерфейс для створення компонентів системи (наприклад, для віконного інтерфейсу, він може створювати вікна і кнопки). Потім пишуться успадковує від нього класи, що реалізують цей інтерфейс.

Мета

Надає інтерфейс для створення сімейств взаємопов'язаних або взаємозалежних об'єктів, не специфікуючи їх конкретних класів

Плюси

ізолює конкретні класи;

спрощує заміну сімейств продуктів;

гарантує сполучуваність продуктів.

Мінуси

складно додати підтримку нового виду продуктів.

Застосовність

Система не повинна залежати від того, як створюються, компонуються і представляються що входять до неї об'єкти; Вхідні в сімейство взаємопов'язані об'єкти повинні використовуватися разом і вам необхідно забезпечити виконання цього обмеження; Система повинна конфігуруватися одним із сімейств складових її об'єктів; потрібно надати бібліотеку об'єктів, розкриваючи тільки їх інтерфейси, але не реалізацію.

Приклад C + +

# Include <iostream>

/ / AbstractProductA

class ICar

{

public:

virtual void info () = 0;

};

/ / ConcreteProductA1

class Ford: public ICar

{

public:

virtual void info ()

{

std:: cout <<"Ford" <<std:: endl;

}

};

/ / ConcreteProductA2

class Toyota: public ICar

{

public:

virtual void info ()

{

std:: cout <<"Toyota" <<std:: endl;

}

};

/ / AbstractProductB

class IEngine

{

public:

virtual void getPower () = 0;

};

/ / ConcreteProductB1

class FordEngine: public IEngine

{

public:

virtual void getPower ()

{

std:: cout <<"Ford Engine 4.4" <<std:: endl;

}

};

/ / ConcreteProductB2

class ToyotaEngine: public IEngine

{

public:

virtual void getPower ()

{

std:: cout <<"Toyota Engine 3.2" <<std:: endl;

}

};

/ / AbstractFactory

class CarFactory

{

public:

ICar * getNewCar ()

{

return createCar ();

}

IEngine * getNewEngine ()

{

return createEngine ();

}

protected:

virtual ICar * createCar () = 0;

virtual IEngine * createEngine () = 0;

};

/ / ConcreteFactory1

class FordFactory: public CarFactory

{

protected:

/ / From CarFactory

virtual ICar * createCar ()

{

return new Ford ();

}

virtual IEngine * createEngine ()

{

return new FordEngine ();

}

};

/ / ConcreteFactory2

class ToyotaFactory: public CarFactory

{

protected:

/ / From CarFactory

virtual ICar * createCar ()

{

return new Toyota ();

}

virtual IEngine * createEngine ()

{

return new ToyotaEngine ();

}

};

int main ()

{

CarFactory * curFactory = NULL;

ICar * myCar = NULL;

IEngine * myEngine = NULL;

ToyotaFactorytoyotaFactory;

FordFactoryfordFactory;

curFactory = & toyotaFactory;

myCar = curFactory-> getNewCar ();

myCar-> info ();

myEngine = curFactory-> getNewEngine ();

myEngine-> getPower ();

delete myCar;

delete myEngine;

curFactory = & fordFactory;

myCar = curFactory-> getNewCar ();

myCar-> info ();

myEngine = curFactory-> getNewEngine ();

myEngine-> getPower ();

delete myCar;

delete myEngine;

return 0;

}

Builder (Будівельник) - шаблон проектування, породжує об'єкти.

Мета

Відокремлює конструювання складного об'єкту від його подання, так що в результаті одного і того ж процесу конструювання можуть виходити різні уявлення.

Плюси

дозволяє змінювати внутрішнє представлення продукту;

ізолює код, що реалізовує конструювання та подання;

дає більш тонкий контроль над процесом конструювання.

Застосування

алгоритм створення складного об'єкта не повинен залежати від того, з яких частин складається об'єкт і як вони стикуються між собою;

процес конструювання повинен забезпечувати різні уявлення конструируемого об'єкта.

Приклад на C + +

# Include <iostream>

# Include <memory>

# Include <string>

/ / Product

class Pizza

{

private:

std:: string dough;

std:: string sauce;

std:: string topping;

public:

Pizza () { }

~ Pizza () { }

void SetDough (const std:: string & d) {Dough = d;};

void SetSauce (const std:: string & s) {Sauce = s;};

void SetTopping (const std:: string & t) {Topping = t;}

void ShowPizza ()

{

std:: cout <<"Yummy!" <<std:: endl

<<"Pizza with Dough as" <<dough

<<", Sauce as" <<sauce

<<"And Topping as" <<topping

<<"!" <<Std:: endl;

}

};

/ / Abstract Builder

class PizzaBuilder

{

protected:

std:: auto_ptr <Pizza> pizza;

public:

PizzaBuilder () {}

virtual ~ PizzaBuilder () {}

std:: auto_ptr <Pizza> GetPizza () { return pizza;}

void createNewPizzaProduct () {Pizza. Reset (New Pizza);}

virtual void buildDough () = 0;

virtual void buildSauce () = 0;

virtual void buildTopping () = 0;

};

/ / ConcreteBuilder

class HawaiianPizzaBuilder: public PizzaBuilder

{

public:

HawaiianPizzaBuilder (): PizzaBuilder () {}

~ HawaiianPizzaBuilder () {}

void buildDough () {Pizza-> SetDough ("cross");}

void buildSauce () {Pizza-> SetSauce ("mild");}

void buildTopping () {Pizza-> SetTopping ("ham and pineapple");}

};

/ / ConcreteBuilder

class SpicyPizzaBuilder: public PizzaBuilder

{

public:

SpicyPizzaBuilder (): PizzaBuilder () {}

~ SpicyPizzaBuilder () {}

void buildDough () {Pizza-> SetDough ("pan baked");}

void buildSauce () {Pizza-> SetSauce ("hot");}

void buildTopping () {Pizza-> SetTopping ("pepperoni and salami");}

};

/ / Director

class Waiter

{

private:

PizzaBuilder * pizzaBuilder;

public:

Waiter (): pizzaBuilder (NULL) {}

~ Waiter () { }

void SetPizzaBuilder (PizzaBuilder * b) {PizzaBuilder = b;}

std:: auto_ptr <Pizza> GetPizza () { return pizzaBuilder-> GetPizza ();}

void ConstructPizza ()

{

pizzaBuilder-> createNewPizzaProduct ();

pizzaBuilder-> buildDough ();

pizzaBuilder-> buildSauce ();

pizzaBuilder-> buildTopping ();

}

};

/ / Клієнт замовляє два піци.

int main ()

{

Waiter waiter;

HawaiianPizzaBuilder hawaiianPizzaBuilder;

waiter. SetPizzaBuilder (& HawaiianPizzaBuilder);

waiter. ConstructPizza ();

std:: auto_ptr <Pizza> pizza = waiter. GetPizza ();

pizza-> ShowPizza ();

SpicyPizzaBuilder spicyPizzaBuilder;

waiter. SetPizzaBuilder (& spicyPizzaBuilder);

waiter. ConstructPizza ();

pizza = waiter. GetPizza ();

pizza-> ShowPizza ();

return EXIT_SUCCESS;

}

Factory Method (Фабричний метод) - шаблон проектування, реалізує ідею "віртуального конструктора", тобто створення об'єктів без явної вказівки їх типу. Відноситься до породжує шаблонами проектування.

Мета

Визначає інтерфейс для створення об'єкту, але залишає підкласами рішення про те, який клас інстанціювати. Фабричний метод дозволяє класу делегувати підкласам.

Використовується, коли:

класу не відомо заздалегідь, об'єкти яких саме класів йому потрібно створювати.

клас спроектовано так, щоб об'єкти, які він створює, специфікувалися підкласами.

клас делегує свої обов'язки одному з кількох допоміжних підкласів, та потрібно локалізувати знання про те, який клас приймає ці обов'язки на себе.

Плюси

дозволяє зробити код створення об'єктів більш універсальним, не прив'язуючись до конкретних класах (ConcreteProduct), а оперуючи лише загальним інтерфейсом (Product);

дозволяє встановити зв'язок між паралельними ієрархіями класів.

Мінуси

необхідність створювати спадкоємця Creator для кожного нового типу продукту (ConcreteProduct).

  • Product - продукт

    • визначає інтерфейс об'єктів, що створюються фабричним методом;

  • ConcreteProduct - конкретний продукт

    • реалізує інтерфейс Product;

  • Creator - творець

    • оголошує фабричний метод, що повертає об'єкт класу Product. Може також містити реалізацію цього методу "за замовчуванням";

    • може викликати фабричний метод для створення об'єкту Product;

  • ConcreteCreator - конкретний творець

    • перевизначає фабричний метод, щоб він створював і повертає об'єкт класу ConcreteProduct.

Приклад на C + +

# Include <iostream>

# Include <string>

using namespace std;

/ / "Product"

class Product {

public:

virtual string getName () = 0;

};

/ / "ConcreteProductA"

class ConcreteProductA: public Product {

public:

string getName () {

return "ConcreteProductA";

}

};

/ / "ConcreteProductB"

class ConcreteProductB: public Product {

public:

string getName () {

return "ConcreteProductB";

}

};

class Creator {

public:

virtual Product * FactoryMethod () = 0;

};

/ / "ConcreteCreatorA"

class ConcreteCreatorA: public Creator {

public:

Product * FactoryMethod () {

return new ConcreteProductA ();

}

};

/ / "ConcreteCreatorB"

class ConcreteCreatorB: public Creator {

public:

Product * FactoryMethod () {

return new ConcreteProductB ();

}

};

int main () {

const int size = 2;

/ / An array of creators

Creator * creators [size];

creators [0] = new ConcreteCreatorA ();

creators [1] = new ConcreteCreatorB ();

/ / Iterate over creators and create products

for (int i = 0; i <size; i + +) {

Product * product = creators [i] -> FactoryMethod ();

cout <<product-> getName () <<endl;

delete product;

}

int a;

cin>> a;

for (int i = 0; i <size; i + +) {

delete creators [i];

}

return 0;

}

Prototype (Прототип) - шаблон проектування, породжує об'єкти.

Призначення

Задає види об'єктів, що створюються за допомогою примірника-прототипу і створює нові об'єкти шляхом копіювання цього прототипу.

Застосовність

Використовуйте цей шаблон проектування, коли система не повинна залежати від того, як в ній створюються, компонуються і представляються продукти:

інстанціруемие класи визначаються під час виконання, наприклад за допомогою динамічного завантаження;

для того щоб уникнути побудови ієрархій класів або фабрик, паралельних ієрархії класів продуктів;

екземпляри класу можуть знаходитися в одному з кількох різних станів. Може виявитися зручніше встановити відповідне число прототипів та клонувати їх, а не інстанціювати щоразу клас вручну у відповідному стані.

Adapter (Адаптер)

Адаптер, Adapter - структурний шаблон проектування, призначений для організації використання функцій об'єкта, недоступного для модифікації, через спеціально створений інтерфейс.

Призначення для організації використання функцій об'єкта, недоступного для модифікації, через спеціально створений інтерфейс (приводить інтерфейс класу (або декількох класів) до інтерфейсу необхідного виду)

Застосовується у випадках система підтримує необхідні дані і поведінку, але має невідповідний інтерфейс. Найчастіше шаблон Адаптер застосовується якщо необхідно створити клас, похідний від знов визначуваного або вже існуючого абстрактного класу.

Завдання

Система підтримує необхідні дані і поведінку, але має невідповідний інтерфейс. Найчастіше шаблон Адаптер застосовується якщо необхідно створити клас, похідний від знов визначуваного або вже існуючого абстрактного класу.

Спосіб рішення

Адаптер передбачає створення класу-оболонки [1] з необхідним інтерфейсом.

Реалізація

Включення вже існуючого класу в інший клас. Інтерфейс включає класу приводиться у відповідність з новими вимогами, а виклики його методів перетворяться у виклики методів включеного класу.

Учасники

Клас Adapter приводить інтерфейс класу Adaptee у відповідність з інтерфейсом класу Target (спадкоємцем якого є Adapter). Це дозволяє об'єкту Client використовувати об'єкт Adaptee так, наче він є екземпляром класу Target.

Наслідки

Шаблон Адаптер дозволяє включати вже існуючі об'єкти в нові об'єктні структури, незалежно від відмінностей в їх інтерфейсах.

Плюси

інкапсуляція реалізації зовнішніх класів (компонентів, бібліотек), система стає незалежною від інтерфейсу зовнішніх класів;

перехід на використання інших зовнішніх класів не вимагає переробки самої системи, достатньо реалізувати один клас Adapter.

Зауваження та коментарі

Шаблон Адаптер дозволяє в процесі проектування не брати до уваги можливі відмінності в інтерфейсах вже існуючих класів. Якщо є клас, що володіє необхідними методами і властивостями (принаймні, концептуально), то при необхідності завжди можна скористатися шаблоном Адаптер для приведення його інтерфейсу до потрібного вигляду.

Близьким Адаптеру є шаблон Фасад, не завжди можна відрізнити один від іншого [2].

Застосування шаблону

Типовим прикладом використання шаблону Адаптер можна назвати створення класів, що приводять до єдиного інтерфейсу функції мови PHP що забезпечують доступ до різних СУБД [3].

Bridge (Міст)

Bridge (Міст) - шаблон проектування, використовуваний в проектуванні програмного забезпечення щоб "розділяти абстракцію і реалізацію так, щоб вони могли змінюватися незалежно". Шаблон bridge (від англ. - Міст) використовує інкапсуляцію, агрегування і може використовувати успадкування для того, щоб розділити відповідальність між класами.

Мета

При частій зміні класу, переваги об'єктно-орієнтованого підходу стають дуже корисними, дозволяючи робити зміни в програмі, маючи мінімальні відомостями про реалізацію програми. Шаблон bridge є корисним там, де не тільки сам клас часто змінюється, але і те, що клас робить.

Опис

Коли абстракція і реалізація розділені, вони можуть змінюватися незалежно. Розглянемо таку абстракцію як фігура. Існує безліч типів фігур, кожна зі своїми властивостями і методами. Однак є щось, що об'єднує всі фігури. Наприклад, кожна фігура повинна вміти малювати себе, масштабуватися ит.п. У той же час малювання графіки може відрізнятися в залежності від типу ОС, чи графічної бібліотеки. Фігури повинні мати можливість малювати себе в різних графічних середовищах, але реалізовувати в кожній фігурі всі способи малювання або модифіковані фігуру щоразу при зміні способу малювання непрактично. У цьому випадку допомагає шаблон bridge, дозволяючи створювати нові класи, які будуть реалізовувати малювання в різних графічних середовищах. При використанні такого підходу дуже легко можна додавати як нові фігури, так і способи їх малювання.

Composite pattern (Компонувальник)

Composite pattern (Компонувальник) - шаблон проектування, об'єднує об'єкти в деревовидну структуру для представлення ієрархії від приватного до цілого. Компонувальник дозволяє клієнтам звертатися до окремих об'єктів і до груп об'єктів однаково.

Опис

Decorator (Декоратор)

Decorator (Декоратор) - структурний шаблон проектування, призначений для динамічного підключення додаткового поведінки до об'єкта. Шаблон Декоратор надає гнучку альтернативу практиці створення підкласів з метою розширення функціональності.

Призначення

Для динамічного підключення до об'єкта додаткових зобов'язань

Завдання

Об'єкт, який передбачається використовувати, виконує основні функції. Однак може знадобитися додати до нього деяку додаткову функціональність, яка буде виконуватися до або після основної функціональності об'єкту.

Спосіб рішення

Декоратор передбачає розширення функціональності об'єкту без визначення підкласів.

Учасники

Клас ConcreteComponent - клас, в який за допомогою шаблону Декоратор додається нова функціональність. У деяких випадках базова функціональність надається класами, похідними від класу ConcreteComponent. У подібних випадках клас ConcreteComponent є вже не конкретним, а абстрактним. Абстрактний клас Component визначає інтерфейс для використання всіх цих класів.

Наслідки

Додається функціональність реалізується в невеликих об'єктах. Перевага полягає в можливості динамічно додавати цю функціональність до або після основної функціональності об'єкту ConcreteComponent.

Реалізація

Створюється абстрактний клас, що представляє як початковий клас, так і нові, що додаються в клас функції. У класах-декоратора нові функції викликаються в необхідній послідовності - до або після виклику подальшого об'єкту.

Зауваження та коментарі

Хоча об'єкт-декоратор може додавати свою функціональність до або після функціональності основного об'єкта, ланцюжок створюваних об'єктів завжди повинна закінчуватися об'єктом класу ConcreteComponent.

Плюси

немає необхідності створювати підкласи для розширення функціональності об'єкта;

можливість динамічно підключати нову функціональність до або після основної функціональності об'єкту ConcreteComponent.

Chain of responsibility (ланцюжок обов'язків)

Ланцюжок обов'язків - поведінковий шаблон проектування, призначений для організації в системі рівнів відповідальності.

Призначення

для організації в системі рівнів відповідальності

Застосування

Шаблон рекомендований для використання в умовах:

в системі, що розробляється є група об'єктів, які можуть обробляти повідомлення певного типу;

всі сполученні повинні бути оброблені хоча б одним об'єктом системи;

повідомлення в системі обробляються за схемою "оброби сам або перейшли іншому", тобто одні повідомлення обробляються на тому рівні, де вони отримані, а інші пересилаються об'єктах іншого рівня.

Command (Команда)

Command (Команда) - шаблон проектування, використовуваний при об'єктно-орієнтованому програмуванні, що представляє дію. Об'єкт команди містить в собі саму дію і його параметри.

Призначення

для обробки команди у вигляді об'єкта

Опис

Забезпечує обробку команди у вигляді об'єкта, що дозволяє зберігати її, передавати в якості параметра методам, а також повертати її у вигляді результату, як і будь-який інший об'єкт.

Наприклад, бібліотека друку може мати клас PrintJob. Для його використання можна створити об'єкт PrintJob, встановити необхідні параметри, і викликати метод, безпосередньо відсилає завдання на друк.

Iterator (Ітератор)

Iterator (Ітератор) - Шаблон проектування. Являє собою об'єкт, що дозволяє послідовний доступ до елементів об'єкта-агрегату без використання описів кожного з об'єктів, що входить до складу агрегації.

Observer (Спостерігач)

Observer (Спостерігач) - поведінковий шаблон проектування. Також відомий як "підлеглі" (Dependents), "видавець-передплатник" (Publisher-Subscriber).

Призначення

Визначає залежність типу "один до багатьох" між об'єктами таким чином, що при зміні стану одного об'єкта всіх залежних від нього сповіщаються про цю подію.

При реалізації шаблону "спостерігач" зазвичай використовуються наступні класи.

Observable - інтерфейс, що визначає методи для додавання, видалення та оповіщення спостерігачів.

Observer - інтерфейс, за допомогою якого спостережуваний об'єкт оповіщає спостерігачів.

ConcreteObservable - конкретний клас, який реалізує інтерфейс Observable.

ConcreteObserver - конкретний клас, який реалізує інтерфейс Observer.

Область застосування

Шаблон "спостерігач" застосовується в тих випадках, коли система має такі властивості:

існує, як мінімум, один об'єкт, розсилають повідомлення

є не менше одного одержувача повідомлень, причому їх кількість і склад можуть змінюватися під час роботи програми.

Даний шаблон часто застосовують в ситуаціях, в яких відправника повідомлень не цікавить, що роблять з наданою ним інформацією одержувачі.

State (Стан)

State (Стан) - шаблон проектування. Використовується в тих випадках, коли під час виконання програми об'єкт повинен міняти свою поведінку в залежності від свого стану.

Паттерн складається з 3 блоків:

Widget - клас, об'єкти якого повинні міняти свою поведінку в залежності від стану.

IState - інтерфейс, який має реалізувати кожне з конкретних станів. Через цей інтерфейс об'єкт Widget взаємодіє зі станом, делегуючи йому виклики методів. Інтерфейс повинен мати засоби для зворотнього зв'язку з об'єктом, поведінка якого потрібно змінити. Для цього використовується подія (патерн Publisher - Subscriber). Це необхідно для того, щоб в процесі виконання програми заміняти об'єкт стану при появі подій. Можливі випадки, коли сам Widget періодично опитує об'єкт стан на наявність переходу.

StateA ... StateZ - класи конкретних станів. Повинні містити інформацію про те, за яких умов і в які стану може переходити об'єкт з поточного стану. Наприклад, з StateA об'єкт може переходити в стан StateB і StateC, а з StateB - назад в StateA і так далі. Об'єкт одного з них має містити Widget при створенні.


Додати в блог або на сайт

Цей текст може містити помилки.

Програмування, комп'ютери, інформатика і кібернетика | Виклад
124.1кб. | скачати


Схожі роботи:
Стереотипи і шаблони спеціальної комунікації
Проектування багатоповерхового будинку 2 Проектування майданчики
Стадії проектування систем автоматизованого проектування
Інвестиційне проектування
Проектування ЛВС
Проектування інфраструктури
Проектування фрегата
Проектування передавача 2
Проектування судів
© Усі права захищені
написати до нас