🔒 Metoda Prywatna
Na samym początku musimy odpowiedzieć sobie na pytanie dlaczego tworzymy metody prywatne:
- potrzebujemy współdzielić kod w conajmniej dwóch innych metodach danej klasy,
- chcemy zredukować złożoność i ukryć pewny spójny logicznie kawałek kodu,
Niewątpliwie są to dobre powody, ale stosowanie metody prywatnej nie jest najlepszym sposobem na uwspólnianie kodu czy redukowania jego złożoności.
💡 Narodziny Konceptu Domenowego
Mamy klasę ShippingService z metodą publiczną getCost zwracającą cenę wysyłki. W samym ciele tej metody zaczyna rosnąć ilość linii kodu weryfikującego czy dostawa powinna być darmowa czy nie. Logika nie jest banalna i na podstawie nowych wytycznych biznesu koncept darmowej wysyłki jest dopiero implementowany w kodzie.
1 2 3 4 5 6 7 8 9 10 11 12 | final class ShippingService { public function getCost(...): Money { // call private method } private function isFree(...): bool { // using class dependencies } } |
Nie wchodząc w szczegóły implementacji, skupmy się na samym fakcie powstania nowej metody prywatnej ShippingService::isFree - czyli zredukwaniu złożonoście metody głównej ShippingService::getCost. Metoda prywatna enkapsuluje warunki podejmujące decyzję czy wysyłka jest darmowa. Wyłonił się tutaj nowy koncept domenowy i niestety jest on zamodelowany za pomoca metody prywatnej.
Problem pojawia się gdy inny serwis również będzie musiał operować na koncepcie darmowej wysyłki. W tym wypadku potrzebny byłby refaktor - upublicznienie metody bądź wydzielenie jej do nowego serwisu nie wydaje się też dobrym rozwiązaniem. Więc jeżeli pozostawimy to w obecnej formie musimy liczyć się z następującymi konsekwencjami:
❌ niemożliwe jest ponowne wykorzystanie metody w innym obszarze,
❌ istnieje ryzyko duplikacji logiki - świadomej (przez lenistwo programisty) / nieświadomej (trudniej odnaleźć logikę w metodzie prywatnej niż w osobnej klasie).
❌ modelowanie konceptów domenowych za pomocą metod serwisowych ogranicza nasze możliwości co do rozwoju konceptów które odzwierciedlają.
![]() |
Koncept domenowy jest ukryty |
⚠️ Metoda jako wyrażanie Konceptu Domenowego
Przechowywanie konceptów domenowych w metodach jest bardzo ograniczające w ich potencjalnym dalszym rozwoju. Istnieje bardzo duża szansa, że sam koncept domenowy z czasem będzie się rozwijał nabierając pełniejszego kształtu.
Jeżeli obecnie oczekujemy tylko odpowiedzi na to czy dla danej kwoty wysyłka jest darmowa to w przyszłości możemy potrzebować np. samego progu cenowego darmowej wysyłki. Wymagałoby to od nas utworzenia kolejnej wyspecjalizowanej metody.
Co więcej przy nieznajomości projektu możemy mieć problemy z ustaleniem czy taki byt w ogóle istnieje w projekcie - z perspektywy katalogów jest on niewidoczny.
Dodatkowo cementujemy logikę biznesową wraz ze sposobem pozyskiwania danych (pobieranie danych z repozytorium) co może prowadzić do ich parametryzacji bądź wydzielenia części logiki do kolejnych metod prywatnych.
🧩 Value Object
Nie jest to wpis o Value Object'cie samym w sobie dlatego tylko wypiszę jego przewagi względem stosowania metod serwisowych:
- jest uniezależniony od kontekstu wywołania,
- nazwa klasy może nadać mu bardziej abstrakcyjny charakter (metoda shippingDays na Value Object ShippingTime::days),
- bardzo łatwy w testowaniu,
- jawna i niezależna jednostka przechowująca wiedzę domenową,
- widoczny z poziomu katalogów,
- bardzo łatwy do ponownego wykorzystania w innym obszarze.
♻️ Refaktoryzacja do Value Object
Pierwszym etapem refaktoryzacji do Value Object'u może być transformacja do prywatnej metody statycznej. W tym wypadku wszystkie parametry wejściowe stałyby się w dalszym toku przekształceń parametrami konstruktora Value Object'u.
Przenosząc odpowiedzialności do Value Object'u i powiązanej z nim Fabryki redukujemy złożonośc samego Serwisu w którym logika ta się wcześniej znajdowała. Zależności przechodzą z Serwisu do Fabryki i to właśnie ona od teraz jest wstrzykiwana do klasy Serwisowej.
![]() |
Przekształcenie metody prywatnej na Value Object |
Brak komentarzy:
Prześlij komentarz