Wzorzec projektowy – prototype

Wzorzec prototyp / prototype polega na klonowaniu wstępnie skonfigurowanego obiektu aby zminimalizować koszty ponownego utworzenia obiektu.  Dzięki temu nasz kod jest czystszy, optymalniejszy oraz wygodniejszy w użyciu. 

Czy prototype pomoże zoptymalizować aplikację?

Pewnie zdarzyła Ci się taka sytuacja, że trzeba było stworzyć n takich samych obiektów na jeden proces. Wraz z czasem ilość tworzonych obiektów powiększała się liniowo co skutkowało coraz dłuższym trwaniem procesu lub jego przerywaniem. Jednym z prostych ale nie zawsze skutecznych optymalizacji jest użycie wzorca prototyp / prototype.

Pokaże Ci na prostym przykładzie z zastosowaniem Symfony 5 oraz Blackfire korzyści płynące z używania prototypu.

Wnioski z optymalizacji za pomocą prototype

Uruchommy teraz blackfire z 10 samplami.

Z użyciem wzorca prototype / prototyp:

Wall Time: 2.74s
Memory: 21.7MB

Bez użycia wzorca:

Wall Time: 8.19s
Memory: 18.9MB
Na tylko tak prostej operacji zmniejszyliśmy czas o 199%. Korzyści jak widać są duże ale przykład też nie jest wyrafinowany i ma pewien mały haczyk. 😉

Aby zobrazować Ci dlaczego prototype może być dużo lepszy względem tworzenia za każdym razem wszystkich klas od zera, w przykładowym kodzie przy każdej iteracji jest tworzony DateTime. W momencie kiedy jest używany prototype, obiekt DateTime jest klonowany. Oczywiście ma to swój koszt, a jest nim to że mamy datę z początku procesu 🙂

Jak wszystko każdy kij ma dwa końce, prototype jest wydajniejszy ale na bardzo dużej ilości obiektów. Pod kątem optymalizacji nie zrobi to dużej różnicy gdy mamy 100 czy 1000 obiektów (chyba że jest to proces np. co 10 sekund)

Prototype a czystość kodu?

Zobaczmy ponownie na poprzedni przykład kodu (nie jest idealny wiem) ale przedstawia w bardzo prosty sposób kolejne korzyści z wykorzystania prototypu.

Dzięki klonowaniu obiektu nie musimy się martwić która to konfiguracja (odchodzą nam ify które jednak zajmują czas całego procesu), bo trzeba któreś pole ustawić z X wartością a drugie z Y itd. Dostarczamy pewien skonfigurowany prototyp który wystarczy klonować.

Dzięki takiej praktyce zyskujemy większą przejrzystość kodu ponieważ nie musimy martwić się o wyczyszczenie pewnych zmiennych w obiekcie, dodawać specjalnie ekstra pola aby ustawić jakąś zmienna prywatną itp.

Kolejną z korzyści jest po prostu debugowanie. Nie musisz za każdym razem dochodzić czy jeśli ten if będzie spełniony to ustawi tą zmienną dla tej konfiguracji itd. itp. Wystarczy że spojrzysz który to będzie prototyp i już widzisz dokładnie co jest ustawienia dla danej konfiguracji.

Ostatnią korzyścią jest po prostu utrzymanie, ponieważ mamy jedno miejsce tworzenia kolejnego obiektu a nie n różnych miejsc bo tu generujemy np. na podstawie przykładu powyżej tagi dla nowych aut a w innym miejscu dla starych aut a jeszcze w innym dla aut ze średniej półki cenowej.

Dwa zdania na koniec

Wzorzec projektowy prototyp / prototype można bardzo fajnie obsłużyć dodając wzorzec registry. W wielkim skrócie registry to fabryka dla prototypów.

Drugim zdaniem chciałbym wspomnieć o klonowaniu w PHP, jest ono ryzykowne. Core PHP nie klonuje z automatu obiektów a co za tym idzie ich referencja jest dalej trzymana ale o tym będzie w innym wpisie podlinkuję tutaj jak się pojawi a tymczasem zapraszam Cię do mojego wpisu o wzorcu projektowym adapter. 🙂

Źródła:

Wzorzec projektowy – prototype
Przewiń na górę