Moje zdanie na ten temat.
Wszystkie cztery wzorce mają ze sobą wiele wspólnego, wszystkie cztery są czasem nieformalnie nazywane opakowaniami lub wzorami opakowań. Wszyscy używają kompozycji, zawijania tematu i delegowania wykonania do tematu w pewnym momencie, odwzorowując jedno wywołanie metody na inne. Oszczędzają klientowi konieczności konstruowania innego obiektu i kopiowania wszystkich istotnych danych. Jeśli są używane mądrze, oszczędzają pamięć i procesor.
Promując luźne sprzęganie, sprawiają, że niegdyś stabilny kod jest mniej narażony na nieuniknione zmiany i lepiej czytelny dla innych programistów.
Adapter
Adapter dostosowuje temat (adapttee) do innego interfejsu. W ten sposób możemy dodać obiekt do zbioru nominalnie różnych typów.
Adapter udostępnia klientowi tylko odpowiednie metody, może ograniczyć wszystkie inne, ujawniając zamiary użytkowania w określonych kontekstach, takie jak adaptacja zewnętrznej biblioteki, sprawiając, że wydaje się ona mniej ogólna i bardziej skoncentrowana na potrzebach naszej aplikacji. Adaptery zwiększają czytelność i własny opis naszego kodu.
Adaptery chronią jeden zespół przed niestabilnym kodem od innych zespołów; narzędzie ratujące życie w kontaktach z zespołami offshore ;-)
Mniej wspomniany ma na celu zapobieganie nadmiarowi adnotacji w klasie przedmiotów. Przy tak wielu ramach opartych na adnotacjach staje się to ważniejsze niż kiedykolwiek.
Adapter pomaga ominąć ograniczenie Java tylko jednego dziedziczenia. Może łączyć kilka adapterów pod jedną kopertą, co daje wrażenie wielokrotnego dziedziczenia.
Pod względem kodu adapter jest „cienki”. Nie powinien dodawać zbyt wiele kodu do klasy adapttee, oprócz zwykłego wywoływania metody adapttee i sporadycznych konwersji danych niezbędnych do wykonywania takich wywołań.
W JDK lub bibliotekach podstawowych nie ma wielu dobrych przykładów adapterów. Twórcy aplikacji tworzą Adaptery, aby dostosować biblioteki do interfejsów specyficznych dla aplikacji.
Dekorator
Dekorator nie tylko deleguje, nie tylko mapuje jedną metodę na drugą, ale robi więcej, modyfikuje zachowanie niektórych metod przedmiotowych, może zdecydować, że w ogóle nie wywoła metody podmiotowej, deleguje do innego obiektu, obiektu pomocnika.
Dekoratorzy zazwyczaj dodają (przezroczystą) funkcjonalność do zawiniętego obiektu, taką jak rejestrowanie, szyfrowanie, formatowanie lub kompresja obiektu. Ta nowa funkcjonalność może przynieść wiele nowego kodu. Dlatego dekoratorzy są zwykle o wiele „grubsi” niż Adaptery.
Dekorator musi być podklasą interfejsu podmiotu. Można ich używać w sposób przejrzysty zamiast tematów. Patrz BufferedOutputStream, nadal jest OutputStream i może być używany jako taki. Jest to główna różnica techniczna w stosunku do adapterów.
Przykłady podręczników dla całej rodziny dekoratorów znajdują się w JDK - Java IO. Wszystkie klasy, takie jak BufferedOutputStream , FilterOutputStream i ObjectOutputStream, są dekoratorami OutputStream . Mogą być warstwami cebuli, gdzie jeden dekorator jest ponownie dekorowany, co zwiększa funkcjonalność.
Pełnomocnik
Serwer proxy nie jest typowym opakowaniem. Zawinięty obiekt, podmiot proxy, może jeszcze nie istnieć w momencie tworzenia proxy. Serwer proxy często tworzy go wewnętrznie. Może to być ciężki obiekt tworzony na żądanie lub obiekt zdalny w innej maszynie JVM lub w innym węźle sieciowym, a nawet obiekt inny niż Java, składnik w natywnym kodzie. Nie musi wcale owijać ani delegować do innego obiektu.
Najbardziej typowymi przykładami są zdalne proxy, inicjatory ciężkich obiektów i proxy dostępu.
Remote Proxy - podmiot znajduje się na zdalnym serwerze, innym JVM lub nawet w systemie innym niż Java. Serwer proxy tłumaczy wywołania metod na wywołania RMI / REST / SOAP lub cokolwiek jest potrzebne, chroniąc klienta przed narażeniem na podstawowe technologie.
Lazy Load Proxy - pełna inicjalizacja obiektu tylko przy pierwszym użyciu lub pierwszym intensywnym użyciu.
Access Proxy - kontroluj dostęp do tematu.
Fasada
Fasada jest ściśle związana z zasadą projektowania najmniejszej wiedzy (Law of Demeter). Fasada jest bardzo podobna do adaptera. Obaj się zawijają, oboje mapują jeden obiekt na inny, ale różnią się intencją. Fasada spłaszcza złożoną strukturę obiektu, złożony wykres obiektu, upraszczając dostęp do złożonej struktury.
Fasada otacza złożoną strukturę, zapewniając płaski interfejs. Zapobiega to narażeniu obiektu klienta na relacje wewnętrzne w strukturze podmiotu, a tym samym sprzyja luźnemu łączeniu.
Most
Bardziej złożony wariant wzorca adaptera, w którym różni się nie tylko implementacja, ale również abstrakcja. Dodaje jeszcze jedno pośrednie przekazanie uprawnień. Dodatkowa delegacja to most. Oddziela adapter nawet od dostosowania interfejsu. Zwiększa złożoność bardziej niż jakikolwiek inny wzór owijania, więc aplikuj ostrożnie.
Różnice w konstruktorach
Różnice w strukturze są również widoczne, gdy patrzymy na ich konstruktorów.
Serwer proxy nie zawija istniejącego obiektu. Konstruktor nie zawiera tematu.
Dekorator i adapter owijają już istniejący obiekt, i taki jest zwykle
dostarczany w konstruktorze.
Konstruktor fasad pobiera element główny z wykresu całego obiektu, w przeciwnym razie wygląda tak samo jak Adapter.
Przykład z życia - adapter Marshalling JAXB . Celem tego adaptera jest odwzorowanie prostej klasy płaskiej na bardziej złożoną strukturę wymaganą zewnętrznie i zapobieganie „zanieczyszczeniu” klasy przedmiotu za pomocą nadmiernych adnotacji.