Відмінності між версіями «Міст (шаблон проектування)»

Матеріал з Вікіпедії — вільної енциклопедії.
Jump to navigation Jump to search
[перевірена версія][перевірена версія]
м
 
(Не показано 3 проміжні версії 3 користувачів)
Рядок 1: Рядок 1:
'''Міст''' ({{lang-en|Bridge}}) — [[шаблони проектування|шаблон проектування]], призначений для того, щоб відділити [[Абстракція даних|абстракцію]] від її конкретної [[Імплементація|імплементації]] таким чином, щоб вони могли бути змінені незалежно один від одного. Відноситься до класу [[структурні шаблони|структурних шаблонів]].
+
'''Міст''' ({{lang-en|Bridge}}) — [[шаблони проектування|шаблон проектування]], призначений для того, щоб відділити [[Абстракція даних|абстракцію]] від її конкретної [[Імплементація|імплементації]] таким чином, щоб вони могли бути змінені незалежно один від одного. Належить до класу [[структурні шаблони|структурних шаблонів]].
   
 
== Призначення ==
 
== Призначення ==
Рядок 5: Рядок 5:
   
 
== Мотивація ==
 
== Мотивація ==
Якщо для деякої абстракції можливо кілька реалізацій, зазвичай застосовують спадкування. Абстрактний клас визначає інтерфейс абстракції, а його конкретні підкласи по-різному реалізують його. Але такий підхід не завжди є достатньо гнучким. Спадкування жорстко прив'язує реалізацію до абстракції, що перешкоджає незалежній модифікації, розширенню та повторному використанню абстракції та її реалізації.
+
Якщо для деякої абстракції можливо кілька реалізацій, зазвичай застосовують наслідування. Абстрактний клас визначає інтерфейс абстракції, а його конкретні підкласи по-різному реалізують його. Але такий підхід не завжди є достатньо гнучким. Наслідування жорстко прив'язує реалізацію до абстракції, що перешкоджає незалежній модифікації, розширенню та повторному використанню абстракції та її реалізації.
   
 
== Застосовність ==
 
== Застосовність ==
Рядок 28: Рядок 28:
   
 
Коли існує тільки одна реалізація, то в [[C++]] цей шаблон називається [[Pimpl]].
 
Коли існує тільки одна реалізація, то в [[C++]] цей шаблон називається [[Pimpl]].
  +
  +
== Переваги ==
  +
  +
* Від'єднання абстракції від реалізації
  +
* Зменшення кількості підкласів
  +
* Чистий код і зменшенням розміру виконуваного файлу
  +
* Інтерфейс і реалізація можуть варіюватися самостійно
  +
* Покращена розширюваність - абстракції та впровадження можуть бути розширені самостійно
  +
  +
== Недоліки==
  +
  +
* Підвищує складність.
  +
* Подвійна спрямованість - це матиме невеликий вплив на продуктивність.
   
 
== Відносини ==
 
== Відносини ==
 
Об'єкт ''Abstraction'' містить у собі ''Implementor'' і перенаправляє йому запити клієнта.
 
Об'єкт ''Abstraction'' містить у собі ''Implementor'' і перенаправляє йому запити клієнта.
  +
  +
== Реалізація ==
  +
=== C++ ===
  +
{{Hider_hiding
  +
| title = Приклад реалізації на мові [[С++]]
  +
| content =
  +
<source lang="cpp">
  +
#include <iostream>
  +
  +
using namespace std;
  +
  +
// ієрархія реалізації
  +
struct IWallCreator
  +
{
  +
virtual void BuildWall() = 0;
  +
virtual void BuildWallWithDoor() = 0;
  +
virtual void BuildWallWithWindow() = 0;
  +
};
  +
// конкретні реалізації
  +
struct BrickWallCreator :public IWallCreator
  +
{
  +
virtual void BuildWall(){ cout << "Brick & mortar wall.\n"; }
  +
virtual void BuildWallWithDoor(){ cout << "Brick & mortar wall with door hole.\n"; }
  +
virtual void BuildWallWithWindow(){ cout << "Brick & mortar wall with window hole.\n";}
  +
};
  +
struct FoamblockWallCreator :public IWallCreator
  +
{
  +
virtual void BuildWall() { cout << "Foam wall.\n"; }
  +
virtual void BuildWallWithDoor() { cout << "Foam wall.\n"; }
  +
virtual void BuildWallWithWindow() { cout << "Foam wall.\n"; }
  +
};
  +
// базовий клас абстракції
  +
class IBuildCompany
  +
{
  +
protected:
  +
IWallCreator* wallCreator; // міст
  +
public:
  +
void setWallCreator(IWallCreator* creator)
  +
{
  +
wallCreator = creator;
  +
}
  +
virtual void BuildFoundation() = 0;
  +
virtual void BuildRoom() = 0;
  +
virtual void BuildRoof() = 0;
  +
};
  +
// конкретні абстракції
  +
struct TownBuildCompany :public IBuildCompany
  +
{
  +
virtual void BuildFoundation(){ cout << "Concrete solid foundation is finished.\n"; }
  +
// визначення методів абстракції через методи реалізацї
  +
virtual void BuildRoom()
  +
{
  +
wallCreator->BuildWallWithWindow();
  +
wallCreator->BuildWall();
  +
wallCreator->BuildWall();
  +
wallCreator->BuildWallWithDoor();
  +
cout << "Room is finished.\n";
  +
}
  +
virtual void BuildRoof() { cout << "Flat roof is finished.\n";}
  +
};
  +
struct CoountryBuildCompany :public IBuildCompany
  +
{
  +
virtual void BuildFoundation() { cout << "Country foundation is finished.\n"; }
  +
virtual void BuildRoom()
  +
{
  +
wallCreator->BuildWallWithDoor();
  +
wallCreator->BuildWallWithWindow();
  +
wallCreator->BuildWallWithWindow();
  +
wallCreator->BuildWall();
  +
cout << "Room is finished.\n";
  +
}
  +
virtual void BuildRoof() { cout << "Roof is finished.\n"; }
  +
};
  +
void main()
  +
{
  +
BrickWallCreator brigade;
  +
FoamblockWallCreator team;
  +
TownBuildCompany Avalon;
  +
CoountryBuildCompany Riel;
  +
  +
cout << "*Avalon* has started the building!\n\n";
  +
Avalon.BuildFoundation();
  +
Avalon.setWallCreator(&team);
  +
Avalon.BuildRoom();
  +
Avalon.BuildRoom();
  +
cout << " the creator of walls was changed\n";
  +
Avalon.setWallCreator(&brigade);
  +
Avalon.BuildRoom();
  +
Avalon.BuildRoof();
  +
cout << "\n*Riel* has started the building!\n\n";
  +
Riel.BuildFoundation();
  +
Riel.setWallCreator(&brigade);
  +
Riel.BuildRoom();
  +
Riel.BuildRoom();
  +
Riel.BuildRoof();
  +
}
  +
</source>
  +
}}
   
 
== Джерела ==
 
== Джерела ==
Рядок 44: Рядок 155:
 
|видання =
 
|видання =
 
|місце = М.
 
|місце = М.
|видавництво = [[Вильямс (издательство)|«Вильямс»]]
+
|видавництво = [[Вільямс (видавництво)|«Вильямс»]]
 
|рік = 2002
 
|рік = 2002
 
|том =
 
|том =

Поточна версія на 09:52, 3 січня 2018

Міст (англ. Bridge) — шаблон проектування, призначений для того, щоб відділити абстракцію від її конкретної імплементації таким чином, щоб вони могли бути змінені незалежно один від одного. Належить до класу структурних шаблонів.

Призначення[ред.ред. код]

Відокремити абстракцію від її реалізації таким чином, щоб перше та друге можна було змінювати незалежно одне від одного.

Мотивація[ред.ред. код]

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

Застосовність[ред.ред. код]

Слід використовувати шаблон Міст у випадках, коли:

  • треба запобігти постійній прив'язці абстракції до реалізації. Так, наприклад, буває коли реалізацію необхідно обрати під час виконання програми;
  • як абстракції, так і реалізації повинні розширюватись новими підкласами. У цьому разі шаблон Міст дозволяє комбінувати різні абстракції та реалізації та змінювати їх незалежно одне від одного;
  • зміни у реалізації не повинні впливати на клієнтів, тобто клієнтський код не повинен перекомпілюватись;
  • треба повністю сховати від клієнтів реалізацію абстракції;
  • треба розподілити одну реалізацію поміж кількох об'єктів (можливо застосовуючи підрахунок посилань), і при цьому приховати це від клієнта.

Структура[ред.ред. код]

UML діаграма, що описує структуру шаблону проектування Міст
  • Abstraction — абстракція:
    • визначає інтерфейс абстракції;
    • зберігає посилання на об'єкт типу Implementor;
  • RefinedAbstraction — уточнена абстракція:
    • розширює інтерфейс, означений абстракцією Abstraction;
  • Implementor — реалізатор:
    • визначає інтерфейс для класів реалізації. Він не зобов'язаний точно відповідати інтерфейсу класу Abstraction. Насправді обидва інтерфейси можуть бути зовсім різними. Зазвичай, інтерфейс класу Implementor надає тільки примітивні операції, а клас Abstraction визначає операції більш високого рівня, що базуються на цих примітивах;
  • ConcreteImplementor — конкретний реалізатор:
    • містить конкретну реалізацію інтерфейсу класу Implementor.

Коли існує тільки одна реалізація, то в C++ цей шаблон називається Pimpl.

Переваги[ред.ред. код]

  • Від'єднання абстракції від реалізації
  • Зменшення кількості підкласів
  • Чистий код і зменшенням розміру виконуваного файлу
  • Інтерфейс і реалізація можуть варіюватися самостійно
  • Покращена розширюваність - абстракції та впровадження можуть бути розширені самостійно

Недоліки[ред.ред. код]

  • Підвищує складність.
  • Подвійна спрямованість - це матиме невеликий вплив на продуктивність.

Відносини[ред.ред. код]

Об'єкт Abstraction містить у собі Implementor і перенаправляє йому запити клієнта.

Реалізація[ред.ред. код]

C++[ред.ред. код]

Джерела[ред.ред. код]

Література[ред.ред. код]

Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5.