Warstwa Abstrakcji - stanowi izolację pomiędzy kodem programisty a zewnętrznymi modułami, pozwala odseparować system od jego zależności przez co czyni go podatnym na zmiany i aktualizacje. Przywiązując system do innej usługi czynimy go słabym.

Jestę Builderę post

2015-10-08

Jestę builderem bo implementuję fluent interface? A może jestem builderem bo buduję? Często te dwa wzorce są ze sobą mylone. Wyjaśnijmy różnicę.

Fluent Interface - metody w klasie zwracają jako rezultat instancję tej klasy przez co można robić coś takiego:

$object->method1()->method2()->method3();

Builder - używany do konstruowania skomplikowanych obiektów mogących przyjąć sporo parametrów, zarówno wymaganych lub opcjonalnych. Od fabryki różni się tym, że z każdym wywołaniem jakiejś metody na builderze tworzona lub rozszerzana jest część budowanego obiektu.

Dlaczego te dwa wzorce są mylone?

Ponieważ najwygodniej jest korzystać z buildera który implementuje fluent interface. Na przykład:

$queryBuilder->add('select', 'u')
   ->add('from', 'User u')
   ->add('orderBy', 'u.name ASC')
   ->setFirstResult( $offset )
   ->setMaxResults( $limit );

Nie wszystko co implementuje fluent interface jest jednak builderem. Pierwszy z brzegu przykład to Eloquent Query Builder W tym wypadku nic nie jest budowane przez builder. Builder wprawdzie coś składa, ale nie zwraca budowanego query, a rezultat jego wykonania. Dlaczego taka konstrukcja może być szkodliwa? Ponieważ zwiększa ilość powodów dla których moglibyśmy chcieć klasę tego buildera zmodyfikować. Pierwszym powodem jest oczywiście rozszerzenie sposobu budowania query. Ponieważ jednak zbudowane query nie jest zwracane, tylko jest używane w celu wykonania odpowiediego zapytania może się okazać, że trzeba będzie buildera modyfikować również z powodu samego wykonania query.

Po co tak rozszerzać buildera? Chociaż by po to żeby dołożyć system zapisywania do logu wykonanych zapytań lub zmodyfikować wszystkie zapytania w celu dołożenia jakiegoś warunku na podstawie parametru locale z requesta. Gdyby query zostało najpierw zbudowane, następnie zwrócone można by z nim coś jeszcze zrobić zanim zostanie przez coś innego wykonane.

Ogólnie sam fluent interface bardziej szkodzi niż pomaga, metody robią co innego niż mówi ich nazwa. Przykładowo od metody "add" można by się spodziewać dodania czegoś, jednak na podstawie nazwy ciężko wywnioskować, że zwróci ona także instancję obiektu, na którym została wywołana. Więcej na temat szkodliwości fluent interface do poczytania na blogu jednego z twórców Doctrine ORM.

Jednak zgodnie z założeniem, że kodu nie można oceniać bez kontekstu, ciężko o stwierdzenie czy ten wzorzec jest jednoznacznie zły czy jednoznacznie dobry. Trzeba mieć bardzo dobry powód, żeby go użyć i takim powodem nie jest ułatwienie wykonywania metod.

Masz pytanie?
Napisz: kontakt@zawarstwaabstrakcji.pl

Feedback

Podobał Ci się ten wpis? Bardzo mnie to cieszy. Nie ma większej motywacji niż zadowolony odbiorca. Gdybyś uznał, że treść którą tworzę jest wartościowa byłbym wdzięczny za zostawienie recenzji na Facebooku. Taka recenzja nie tylko zmotywuje mnie do dalszej pracy ale pozwoli również zyskać większy zasięg. Zasięg, który pozwoli mi dotrzeć do większej grupy odbiorców.
Możesz też polubić fanpage, na którym staram się w miarę regularnie publikować krótsze ale nie mniej wartościowe treści.

Akceptuję

Ten serwis używa plików cookies. Więcej o plikach cookies.