Bridge

Przeznaczenie

  • Umożliwia różnicowanie implementacji i abstrakcji przez umieszczenie obu elementów w osobnych hierarchiach klas

  • Bardziej elastyczny sposób separacji abstrakcji od implementacji niż stosowanie dziedziczenia

Kontekst

  • Istnieje wiele implementacji, które muszą być uwzględnione w projekcie

  • Klient korzysta z abstrakcyjnych klas w celu ujednolicenia interfejsu

Problem

  • Chcemy uniknąć stałego powiązania abstrakcji z jej implementacją – implementacja może być wybierana lub zmieniana w czasie wykonywania programu

  • Oczekujemy zmian zarówno w interfejsie abstrakcji jak i w implementacjach

  • Zmiany w implementacji abstrakcji nie powinny mieć wpływu na klientów

  • Chcemy całkowicie ukryć implementację abstrakcji przed klientami

  • Chcemy, żeby wiele obiektów współdzieliło implementację (np. używając liczników odwołań) i żeby ukryć to przed klientami

Struktura

_images/Bridge.png

Uczestnicy

Abstraction

  • definiuje interfejs abstrakcji

  • zarządza odwołaniem do obiektu typu Implementacja

RefinedAbstraction – rozszerza interfejs zdefiniowany przez klasę Abstraction

Implementor

  • definiuje interfejs klas implementujących, który nie musi dokładnie odpowiadać interfejsowi klasy Abstraction

  • zwykle interfejs implementacji określa jedynie operacje pierwotne, a Abstraction – wykorzystujące je operacje wyższego rzędu

ConcreteImplementor – implementuje interfejs klasy Implementor i definiuje jej implementację konkretną

Współpraca

Abstraction przesyła żądania klientów do swojego obiektu implementacji Implementor.

Konsekwencje

  1. Separuje implementację, usuwając jej trwałe powiązanie z interfejsem. Implementacja abstrakcji może być ustalana w czasie wykonywania programu. Eliminuje zależność w czasie kompilacji od określonej implementacji.

  2. Ułatwiona rozszerzalność. Można niezależnie rozbudowywać hierarchie abstrakcji i implementacji.

  3. Zmiany w klasach rzeczywistych abstrakcji nie wpływają na klienta.

  4. Przydatny w systemach graficznych i okienkowych, które muszą pracować na różnych platformach.

  5. Zwiększa złożoność projektu.

Implementacja

Istnienie tylko jednej klasy implementacji.

Wzorce pokrewne

  1. Abstract factory – może tworzyć i konfigurować poszczególne „mosty”.

  2. Adapter:

  • dzięki temu wzorcowi niepowiązane ze sobą klasy mogą współpracować,

  • zwykle stosuje się go zaraz po zaprojektowaniu systemu, „mostu” natomiast używa się od samego początku projektowania,

  • chodzi o to, by abstrakcje i implementacje mogły się zmieniać niezależnie jedna od drugiej.