Pytanie stanowi fałszywy dylemat. Właściwe stosowanie zasady YAGNI nie jest niczym niepowiązanym. To jeden z aspektów dobrego projektu. Każda z zasad SOLID jest również aspektem dobrego projektowania. Nie zawsze możesz w pełni zastosować każdą zasadę w dowolnej dyscyplinie. Problemy w świecie rzeczywistym nakładają na kod wiele sił, a niektóre z nich popychają w przeciwnych kierunkach. Zasady projektowania muszą uwzględniać je wszystkie, ale żadna garść zasad nie pasuje do wszystkich sytuacji.
Spójrzmy teraz na każdą zasadę ze zrozumieniem, że chociaż czasami mogą one zmierzać w różnych kierunkach, nie są one z natury rzeczy w konflikcie.
YAGNI został stworzony, aby pomóc programistom uniknąć szczególnego rodzaju przeróbek: tego, co wynika z budowania niewłaściwej rzeczy. Robi to, prowadząc nas do unikania zbyt wczesnych błędnych decyzji w oparciu o założenia lub prognozy dotyczące tego, co naszym zdaniem zmieni się lub będzie potrzebne w przyszłości. Wspólne doświadczenie mówi nam, że kiedy to robimy, zwykle się mylimy. Na przykład YAGNI powiedziałby ci, żebyś nie tworzył interfejsu w celu ponownego użycia , chyba że wiesz już , że potrzebujesz wielu implementatorów. Podobnie YAGNI powiedziałbym nie stworzyć „ScreenManagera” zarządzać jednego formularza w aplikacji, chyba że wiesz już teraz , że masz zamiar mieć więcej niż jeden ekran.
W przeciwieństwie do tego, co myśli wielu ludzi, SOLID nie polega na możliwości ponownego użycia, generyczności, a nawet abstrakcji. SOLID ma na celu pomóc Ci napisać kod, który jest przygotowany na zmianę , nie mówiąc nic o tym, jaka może być ta konkretna zmiana. Pięć zasad SOLID tworzy strategię budowania kodu, która jest elastyczna, nie jest zbyt ogólna i prosta, nie będąc naiwna. Właściwe stosowanie kodu SOLID tworzy małe, skoncentrowane klasy o ściśle określonych rolach i granicach. Praktycznym rezultatem jest to, że przy każdej potrzebnej zmianie wymagań należy dotknąć minimalną liczbę klas. Podobnie, przy każdej zmianie kodu istnieje zminimalizowana ilość „falowania” do innych klas.
Patrząc na przykładową sytuację, zobaczymy, co mogliby powiedzieć YAGNI i SOLID. Rozważasz wspólny interfejs repozytorium, ponieważ wszystkie repozytoria wyglądają tak samo z zewnątrz. Ale wartością wspólnego, ogólnego interfejsu jest możliwość korzystania z dowolnego z implementatorów bez konieczności określania, który z nich jest konkretny. O ile w Twojej aplikacji nie ma takiego miejsca, w którym byłoby to konieczne lub przydatne, YAGNI mówi, nie rób tego.
Do obejrzenia jest 5 SOLIDNYCH zasad. S to pojedyncza odpowiedzialność. Nie mówi to nic o interfejsie, ale może powiedzieć coś o twoich konkretnych klasach. Można argumentować, że za obsługę samego dostępu do danych najlepiej może odpowiadać jedna lub więcej innych klas, podczas gdy odpowiedzialność repozytoriów polega na tłumaczeniu z kontekstu niejawnego (CustomerRepository jest repozytorium niejawnie dla podmiotów klienta) na jawne wywołania do uogólniony interfejs API dostępu do danych określający typ jednostki klienta.
O jest otwarte-zamknięte. Chodzi głównie o dziedziczenie. Miałoby to zastosowanie, gdybyś próbował czerpać swoje repozytoria ze wspólnej bazy implementującej wspólną funkcjonalność lub gdybyś spodziewał się, że będziesz czerpał dalej z różnych repozytoriów. Ale nie jesteś, więc nie.
L oznacza substytucyjność Liskowa. Ma to zastosowanie, jeśli zamierzasz korzystać z repozytoriów za pośrednictwem wspólnego interfejsu repozytorium. Nakłada ograniczenia na interfejs i implementacje, aby zapewnić spójność i uniknąć specjalnego obchodzenia się z różnymi impelementerami. Powodem tego jest to, że taka specjalna obsługa podważa cel interfejsu. Przydatne może być rozważenie tej zasady, ponieważ może to ostrzec cię przed używaniem wspólnego interfejsu repozytorium. Jest to zgodne z wytycznymi YAGNI.
I to Segregacja interfejsu. Może to mieć zastosowanie, jeśli zaczniesz dodawać różne operacje zapytań do swoich repozytoriów. Segregacja interfejsu ma zastosowanie tam, gdzie można podzielić członków klasy na dwa podzbiory, z których jeden będzie używany przez niektórych konsumentów, a drugi przez innych, ale żaden konsument prawdopodobnie nie użyje obu podzbiorów. Wytyczne dotyczą utworzenia dwóch oddzielnych interfejsów zamiast jednego wspólnego. W twoim przypadku jest mało prawdopodobne, że pobieranie i zapisywanie pojedynczych instancji byłoby zajęte przez ten sam kod, który przeprowadzałby ogólne zapytania, więc może być przydatne rozdzielenie ich na dwa interfejsy.
D to wstrzyknięcie zależne. Wracamy do tego samego punktu, co S. Jeśli podzieliłeś zużycie interfejsu API dostępu do danych na osobny obiekt, ta zasada mówi, że zamiast tylko nowego wystąpienia tego obiektu, powinieneś przekazać go podczas tworzenia repozytorium. Ułatwia to kontrolowanie żywotności komponentu dostępu do danych, otwierając możliwość udostępniania referencji do niego między repozytoriami, bez konieczności podejmowania decyzji o uczynieniu go singletonem.
Należy zauważyć, że większość zasad SOLID niekoniecznie ma zastosowanie na tym konkretnym etapie tworzenia aplikacji. Na przykład to, czy należy zerwać dostęp do danych, zależy od tego, jak skomplikowane jest to zadanie i czy chcesz przetestować logikę repozytorium bez wchodzenia do bazy danych. Wygląda na to, że jest to mało prawdopodobne (niestety, moim zdaniem), więc prawdopodobnie nie jest konieczne.
Po tych wszystkich rozważaniach okazuje się, że YAGNI i SOLID rzeczywiście zapewniają jedną wspólną, solidną, natychmiastową poradę: prawdopodobnie nie jest konieczne tworzenie wspólnego ogólnego interfejsu repozytorium.
Cała ta uważna myśl jest niezwykle przydatna jako ćwiczenie edukacyjne. Nauka zajmuje dużo czasu, ale z czasem rozwijasz intuicję i staje się bardzo szybka. Będziesz wiedział, co należy zrobić, ale nie musisz myśleć o wszystkich tych słowach, chyba że ktoś poprosi cię o wyjaśnienie przyczyny.