Wzorce projektowe: Budowniczy(Builder) Fluent Interface oraz Klasyczny Builder

W tej lekcji o wzorcu projektowym Builder, a raczej dwóch jego rodzajach, które mają zastosowanie do sposobu tworzenia obiektu klasy, oraz tworzenia obiektu z innych obiektów. Więcej szczegółów dalej w artykule.

Opis i sposób implementacji

Celem buildera jest oddzielenie sposobu tworzenia obiektu od jego reprezentacji. Czyli proces tworzenia obiektu jest podzielony na pare części.

Najpierw pokaże przykład buildera na zasadzie Fluent Interface, potem klasycznego buildera.

Buildera Fluent Interface powinno implementować się wtedy kiedy konstruktor ma więcej niż cztery lub pięć parametrów, tworzymy klasę buildera, wewnątrz tej klasy, która ma ten konstruktor z tymi wieloma parametrami.

Przykłady w których Fluent Interface Builder nadawałby się do zastosowania to wszędzie tam gdzie mamy konstruktory, które przyjmują wiele parametrów, a klasyczny Builder np w oprogramowaniu przyjmującym jakieś dane wejściowe, konwertujące je i na podstawie danych wejściowych, tworzy dane wyjściowe, czyli np w jakieś grze gdzie pod wpływem działań użytkownika, gra wykonuje określone zdarzenia, builderem będzie tutaj kod tworzący określone zdarzenia w grze w zależności od wyborów użytkownika.

 

Builder Fluent Interface

Jednak my odniesiemy do naszego przykładu Sklepu, była tam taka klasa Client:

 

Dodajmy tak pare innych zmiennych np adres zamieszkania klienta, ulicę, numer domu i miasto:

 

Nie wygląda to zbyt czytelnie, gdy użyjemy tu fluent buildera nie tylko będzie to o wiele bardziej czytelne, ale również będziemy mieli oddzielony proces tworzenia danych klienta od manipulowania, reprezentowania ich gdybyśmy chcieli później coś robić z tymi danymi, więc teraz zaimplementujmy tu fluent buildera w sposób pokazany poniżej:

 

Jak widać oddzieliliśmy zapisywanie danych klienta od reszty logiki, oraz możemy w większym stopniu kontrolować to jak jest tworzony obiekt.

Również zapisywanie danych w funkcji „Main” jest o wiele bardziej czytelne:

 

Teraz widać jakie dane są zapisywane do obiektu.

Wynik:

To jest builder fluent Interface, teraz zrobimy sobie przykład klasycznego buildera.

 

Klasyczny Builder

 

Struktura

Najpierw zobaczmy jak wygląda diagram UML Buildera:

Scheme of Builder

Klasa Converter jak widać, tworzy, instancje poszczególnych klas, które odczytują różne formaty danych, a tutaj klasa Reader jest można powiedzieć klientem, który tylko odczytuje te formaty.

Przykładem buildera może być np klient, który zamawia jedzenie z restauracji, popatrz na poniższy obrazek:

Example of Builder

Najpierw klient zamawia posiłek, potem zgłoszenie przychodzi do kierownika, który potem mówi o tym pracownikom, którzy później wykonują zamówienie razem z dowózką do domu. W kodzie zrobimy przykład naszego sklepu.

 

Przykład

Zbudujmy nasz sklep oddzielmy jego obiekty np w ten sposób ściany, dach, podłogę jak to będzie wyglądać w klasycznym builderze?

Przykład może na początku przerazić, ale spokojnie tak naprawde jest to prosty wzorzec tylko trzeba przerobić go w praktyce.

Będę tłumaczył po kolei kawałki całego kodu, cały przykład podam na końcu lekcji w plikach źródłowych, ponieważ jest on długi.

Klasycznego buildera można traktować jak plan.

Diagram stworzonego sklepu wygląda tak:

Dodajemy do klasy Shop, dach, podłogę, oraz ścianę, następnie tworzymy obiekt sklepu za pomocą kierownika w kliencie, czyli w naszym przypadku w funkcji „Main”, całość jest zaprojektowana tak żeby klient nie widział jak jest tworzony sklep zleca jego budowę budowniczemu czyli odnosząc się do naszego kodu klasie Director, i dobrze klienta nie obchodzi jak jest budowany sklep jemu jest dostarczany tylko gotowy produkt.

Zobaczmy teraz jak to wygląda w kodzie, zacznijmy od lewej strony diagramu czyli klas Shop, Roof, Floor, Wall:

Shop:

 

Floor:

 

Roof:

 

Wall:

 

Implementujemy w klasie sklep jego elementy, jednak w postaci interfejsów, trzymamy się piątej zasady SOLID, dependency inversion, zależności między klasami powinny wynikać z abstrakcji oraz moduły wysokopoziomowe nie powinny zależeć od modułów niskopoziomowych, u nas sklep jest modułem wysokopozimowym a dach, podłoga, ściana są modułami niskopoziomowymi, takie małe przypomnienie odnośnie zasad SOLID 🙂

Nasz builder wygląda tak:

 

Jest interfejsem, który implementujemy do klasy sklepu, który chcemy zbudować a chcemy zbudować duży sklep Tesco 🙂

Wygląda ona tak:

 

Ustawiamy w metodach klasy BigShopTesco parametry ustawiające jej elementy i zapisujemy je do interfejsów klasy Shop.

A metody klasy BigShopTesco wywołujemy już w naszym kierowniku, czyli w klasie ShopDirector:

 

Do konstruktora klasy ShopDirector przekazujemy obiekt klasy, który chcemy stworzyć czyli BigShopTesco i wywołujemy jego metody.

A od strony klienta wygląda to tak:

 

Jak widać klient nie widzi jak jest zbudowany sklep i tak powinno być jego to nie obchodzi o to po prostu zleca kierownikowi.

Na koniec lekcji podam kod źródłowy do tego buildera.

Pamiętaj, bezsensu to tylko czytać, żeby to zrozumieć najlepiej stworzyć własnego buildera, możesz wspomagać się tym co ja zrobiłem w celu zrobienia własnego buildera. Bez praktyki nie zrozumiesz tego.

Buildera w obu przypadkach trzeba używać rozsądnie, ponieważ gdy będziemy mielu dużo tych builderów wtedy kod staje się nieczytelny.

Wynik:

 

Zalety i wady

Zalety

  • duża skalowalność(tworzenie nowych danych jest łatwiejsze)
  • Większa możliwość kontrolowania tego jak tworzony jest obiekt(Proces tworzenia obiektu jest niezależny od jego innych reprezentacji)
  • Większa czytelność(przy właściwym zastosowaniu 🙂 )
  • Duże zróżnicowanie wnętrza klas.

Wady

  • Duża liczba obiektów
  • Niewłaściwe stosowanie tego wzorca może spowodować nieczytelność kodu(jeden obiekt może zawierać zbyt wiele budowniczych)

 

Powiązania z innymi wzorcami

 

Podsumowanie

Długa ta lekcja nam wyszła, ale chyba to dobrze bo builder został mam nadzieję dosyć dobrze wytłumaczony.

I to wszystko na temat wzorca Budowniczy(Builder)🙂

Link do githuba ze wszystkimi przykładami: https://github.com/Slaw145/BuilderTutorial

W następnym artykule, będzie mowa o wzorcu Fabryka abstrakcyjna(Abstract Factory).

Standardowo, przypominam o newsletterze, którym wysyłam powiadomienia o nowych wpisach oraz dodatkowe informacje na temat, ogółem mówiąc, świecie IT.

KONIECZNIE dołącz do społeczności DevmanCommunity na fb, części społeczności jest w jednym miejscu 🙂

-strona na fb: Devman.pl-Sławomir Kowalski

-grupa na fb: DevmanCommunity

Pytaj, komentuj pod spodem na końcu wpisu, podziel się nim, oceń go, rób co wolisz🙂

Do zobaczenia 🙂

 
Jeśli ten wpis ci się przydał podziel się nim ze swoimi znajomymi :)

Post a comment

Be first!

avatar
  Subscribe  
Notify about