Flyweight

Przeznaczenie

  • Wykorzystuje współdzielenie obiektów (nazywanych obiektami Flyweight) w celu efektywnej obsługi wielkiej liczby obiektów

Kontekst

  • W projekcie istnieje olbrzymia liczba obiektów

  • Koszt związany z przechowywaniem tych obiektów w pamięci jest znaczący

Problem

  • Chcemy ograniczyć koszty, związane z przechowywaniem obiektów w pamięci współdzieląc obiekty w postaci pyłków

Obiekt Flyweight

Flyweight jest współdzielonym obiektem, który może być używany jednocześnie w wielu kontekstach.

  • Działa jako obiekt niezależny w każdym kontekście dzięki rozróżnieniu stanu na wewnętrzny i zewnętrzny

    • stan wewnętrzny – jest przechowywany w pyłku; składa się z informacji, które są niezależne od kontekstu

    • stan zewnętrzny – zależy od kontekstu i zmienia się w zależności od niego; nie może być współdzielony

  • Po usunięciu stanu zewnętrznego wiele grup obiektów można zastąpić stosunkowo niewielką liczbą współdzielonych obiektów

  • Pyłki modelują pojęcia lub byty, które zwykle są zbyt liczne, żeby przedstawiać je za pomocą obiektów

Struktura

_images/Flyweight.png

Uczestnicy

Flyweight – deklaruje interfejs, poprzez który pyłki mogą otrzymywać stan zewnętrzny i działać zgodnie z nim

ConcreteFlyweight

  • implementuje interfejs pyłku i dodaje pamięć do przechowywania stanu wewnętrznego

  • obiekt klasy ConcreteFlyweight musi dawać się współdzielić

UnsharedConcreteFlyweight

  • nie wszystkie podklasy pyłku muszą być współdzielone

  • klasa abstrakcyjna Flyweight umożliwia współdzielenie ale go nie wymusza

FlyweightFactory

  • tworzy obiekty typu Flyweight

  • zapewnia właściwe współdzielenie pyłków – gdy klient zażąda pyłku, obiekt klasy FlyweightFactory dostarcza istniejący pyłek, lub tworzy nowy, o ile takiego obiektu nie ma

Client

  • utrzymuje odwołania do pyłku (pyłków)

  • wylicza lub przechowuje stan zewnętrzny pyłku (pyłków)

Współpraca

Stan, którego pyłek potrzebuje do działania musi być scharakteryzowany jako wewnętrzny, albo zewnętrzny:

  • stan wewnętrzny jest przechowywany w obiekcie ConcreteFlyweight

  • stan zewnętrzny jest przechowywany lub wyliczany przez obiekt klasy Client

Klienci nie powinni bezpośrednio tworzyć egzemplarzy klasy ConcreteFlyweight. Muszą otrzymywać te obiekty wyłącznie z instancji klasy FlyweightFactory. Gwarantuje to poprawne współdzielenie pyłków.

Konsekwencje

Zmniejszenie zużycia pamięci kosztem zwiększenia czasu wykonywania. Oszczędności pamięci zależą od kilku czynników:

  • zmniejszenia łącznej liczby egzemplarzy, wynikającego ze współdzielenia,

  • wielkości stanu wewnętrznego przypadającego na obiekt,

  • tego, czy stan zewnętrzny jest wyliczany, czy przechowywany.

Implementacja

  1. Usuwanie stanu zewnętrznego. Możliwość stosowania wzorca zależy od łatwości określenia stanu zewnętrznego i usunięcia go ze współdzielonych obiektów.

  2. Zarządzanie współdzielonymi obiektami. Klienci nie powinni ich tworzyć bezpośrednio. FlyweightFactory umożliwia klientom odnajdowanie określonych pyłków.

Podsumowanie

  1. Wykorzystuje współdzielenie obiektów w celu efektywnej obsługi wielkiej liczby obiektów.

  2. Zmniejsza zużycie pamięci kosztem wydłużenia czasu wykonywania.

  3. Skuteczność pyłku zależy od tego ile informacji uda się przenieść do stanu zewnętrznego.