Jestem przy projekcie TDD, więc staram się jak najlepiej trzymać dobrych praktyk związanych z tego rodzaju rozwojem. Jednym z nich jest unikanie w jak największym stopniu statycznego i globalnego.
Mam do czynienia z tym problemem: mam obiekt „artykuł”, który może mieć powiązane z nim „opcje” (dodatkowe „mikro-artykuły”).
Nie mogę wymyślić, jak zastosować dobre podejście, które nie przyniesie efektów nieproduktywnych lub nie wygeneruje zbyt wielu zapytań, ponieważ byłbym w sytuacji, w której wszystko jest tak oddzielone, że w zasadzie będę musiał wykonać 1 zapytanie na obiekt.
Z mojej obecnej perspektywy widzę 3 opcje:
1) Zbuduj artykuł wewnętrzny:
class Article
{
//[...]
public function getArrOption(){
//Build an array of Options instance.
//return an array of Options.
}
}
Pro: prosto
Const: Maintenanceability: Obiekt artykułu zawiera teraz logikę budowania dla obiektu Option. Prawdopodobnie doprowadzi to do duplikacji kodu.
2) Korzystanie z opcjiFactory
class Article
{
//[...]
public function getArrOption(){
return OptionFactory::buildFromArticleId($this->getId());
}
}
Pro: Logika budowy nie jest poza klasą artykułów
Const: Łamię zasadę „statyczny jest trudny do kpienia”, co utrudnia testowanie mojej klasy artykułów.
3) Oddziel wszystkie logiki.
//Build the array of Option instance in a controller somewhere, using a Factory:
$arrOption = OptionFactory::buildFromArticleId($article->getId());
Pro: Artykuł radzi sobie tylko z własną odpowiedzialnością i nie dba o link „ojca” do opcji. Rzeczy są naprawdę oddzielone
Const: Będzie wymagał więcej kodu wewnątrz Kontrolera za każdym razem, gdy będę potrzebował uzyskać dostęp do Opcji. Oznacza to, że nigdy nie powinienem używać fabryki wewnątrz obiektu, a to brzmi dla mnie trochę utopijnie ...
Jaka jest najlepsza droga? (Czy coś przeoczyłem?) Dzięki.
Edytować:
Nie wspominając już o tym, że jeśli nie mogę zadzwonić do fabryki wewnątrz klasy, w zasadzie nigdy nie mogę użyć leniwego wzorca inicjalizacji ...
źródło
Odpowiedzi:
Statyczne nie jest „złe”, jest niemożliwe do wyśmiewania. Nadal możesz go używać tam, gdzie drwiny nie mają sensu.
To nie jest wzór fabryczny, wygląda jak wzór repozytorium, chociaż może nie być. Fabryka to miejsce, w którym masz wiele klas z tym samym interfejsem / klasą podstawową i chcesz oddzielić logikę, która decyduje, którą klasę zwrócić. Repozytorium pobiera dane ze swojego repozytorium, wyodrębniając implementację tego repozytorium (artykuł nie musi wiedzieć, czy jego opcje są przechowywane w tym samym DB, innym, pliku XML, pliku CSV, cokolwiek).
Zignorowałeś możliwość nadania klasie Article obiektu ObjectFactory (lub repozytorium lub cokolwiek innego) w konstruktorze, na którym może on wywołać metodę buildFromArticle.
Mój PHP jest zardzewiały, ale myślę, że wygląda to tak:
Myślę, że to spełnia wszystkie twoje zalety powyżej.
źródło
Oto cytat z papieru, który dowodzi, że nigdy nie potrzebujesz metod statycznych, że wykazano, że abstrakcyjne fabryki są mylące, i sugeruje niewielką zmianę języka w kierunku wstrzykiwania zależności jako rozwiązania.
„Seuss: Obowiązki oddzielenia od metod statycznych w celu szczegółowej konfiguracji”
Link do maszyny Wayback
źródło