Czy przestrzeganie SOLID prowadzi do napisania frameworka na szczycie stosu technologii?

70

Lubię SOLID i staram się go używać i stosować podczas programowania. Ale nie mogę się oprzeć wrażeniu, że podejście SOLID zmienia kod w kod „framework” - tj. Kod, który zaprojektowałbyś, gdybyś tworzył strukturę lub bibliotekę dla innych programistów.

Zazwyczaj ćwiczyłem 2 tryby programowania - tworzenie mniej więcej dokładnie tego, o co pytamy za pomocą wymagań i KISS (typowe programowanie), lub tworzenie bardzo ogólnej i logiki wielokrotnego użytku, usług itp., Które zapewniają elastyczność, jakiej inni programiści mogą potrzebować (programowanie ramowe) .

Jeśli użytkownik naprawdę chce, aby aplikacja wykonywała x i y rzeczy, czy warto podążać za SOLID i dodawać całą masę punktów wejścia do abstrakcji, skoro nawet nie wiesz, czy to w ogóle prawidłowy problem na początek z? Jeśli dodasz te punkty wejścia do abstrakcji, czy naprawdę spełniasz wymagania użytkowników, czy tworzysz strukturę na podstawie istniejącej struktury i stosu technologicznego, aby ułatwić przyszłe dodawanie? W którym przypadku służysz interesom klienta lub programisty?

Jest to coś, co wydaje się powszechne w świecie Java Enterprise, gdzie wydaje się, że projektujesz własną platformę na J2EE lub Spring, aby był to lepszy UX dla programisty, zamiast skupiać się na UX dla użytkownika?

Igneous01
źródło
12
Problemem w przypadku większości krótkich zasad programowania jest to, że podlegają one interpretacji, przypadkowym przypadkom, a czasami definicje słów w takich regułach są niejasne przy bliższej kontroli. Mogą one zasadniczo oznaczać wiele różnych rzeczy dla różnych ludzi. Posiadanie jakiegoś nieideologicznego pragmatyzmu zazwyczaj pozwala podejmować mądrzejsze decyzje.
Mark Rogers
1
Wygląda na to, że przestrzeganie zasad SOLID w jakiś sposób oznacza dużą inwestycję, dużo dodatkowej pracy. Nie ma, jest praktycznie za darmo. I prawdopodobnie zaoszczędzi Tobie lub komuś innemu dużą inwestycję w przyszłość, ponieważ ułatwia utrzymanie i rozszerzenie kodu. Dalej zadajesz pytania typu „czy powinniśmy odrobić pracę domową, czy zadowolić klienta?” To nie są kompromisy.
Martin Maat
1
@MartinMaat Myślę, że bardziej ekstremalne formy SOLID oznaczają duże inwestycje. To znaczy. Oprogramowanie firmowe. Poza oprogramowaniem dla przedsiębiorstw nie miałbyś zbyt wiele powodów, aby wyodrębniać ORM, stos technologii lub bazę danych, ponieważ istnieje bardzo duża szansa, że ​​będziesz trzymać się wybranego stosu. W tym samym sensie, przywiązując się do konkretnego frameworka, bazy danych lub ORM, łamiesz zasady SOLID, ponieważ jesteś powiązany ze swoim stosem. Ten poziom elastyczności SOLID nie jest wymagany w większości zadań.
Igneous01,
1
Zobacz także efekt platformy wewnętrznej .
Maxpm
1
Przekształcenie większości kodu w coś w rodzaju szkieletu wcale nie brzmi okropnie. Staje się okropny tylko wtedy, gdy zostanie przeprojektowany. Ale ramy mogą być minimalne i opiniotwórcze. Nie jestem pewien, czy byłaby to nieunikniona konsekwencja podążania za SOLID, ale jest to zdecydowanie możliwa konsekwencja, którą, jak sądzę, powinieneś przyjąć.
Konrad Rudolph,

Odpowiedzi:

84

Twoja obserwacja jest prawidłowa, zasady SOLID są opracowane przez IMHO z myślą o bibliotekach wielokrotnego użytku lub kodzie szkieletowym. Kiedy śledzisz je wszystkie na ślepo, nie pytając, czy ma to sens, czy nie, ryzykujesz nadmierną generalizacją i zainwestuje w swój system więcej wysiłku, niż to prawdopodobnie konieczne.

Jest to kompromis i wymaga pewnego doświadczenia, aby podejmować właściwe decyzje dotyczące tego, kiedy uogólnić, a kiedy nie. Możliwym podejściem jest trzymanie się zasady YAGNI - nie rób z kodu SOLID „na wszelki wypadek” - lub, używając słów: nie

zapewniają elastyczność, której mogą potrzebować inni programiści

Zamiast zapewnić elastyczność inni deweloperzy faktycznie potrzeba , jak tylko jest to potrzebne , ale nie wcześniej.

Tak więc, ilekroć masz w kodzie jedną funkcję lub klasę, nie masz pewności, czy można ją ponownie wykorzystać, nie umieszczaj jej teraz w swoim środowisku. Poczekaj, aż będziesz mieć rzeczywistą skrzynkę do ponownego użycia, i przeprowadź refakturę do „SOLID wystarczającej ilości dla tej skrzynki”. Nie wdrażaj większej konfigurowalności (zgodnie z OCP) lub punktów wejścia abstrakcji (za pomocą DIP) do takiej klasy, jakiej naprawdę potrzebujesz w przypadku rzeczywistego ponownego użycia. Dodaj kolejną elastyczność, gdy faktycznie istnieje kolejne wymaganie ponownego użycia.

Oczywiście ten sposób pracy zawsze będzie wymagał pewnej refaktoryzacji w istniejącej, działającej bazie kodu. Dlatego ważne są tutaj testy automatyczne. Zatem sprawienie, by Twój kod był wystarczająco SOLIDNY ​​od samego początku, aby mógł być testowany jednostkowo, nie jest stratą czasu, a robienie tego nie jest sprzeczne z YAGNI. Testy automatyczne są ważnym przypadkiem „ponownego użycia kodu”, ponieważ dany kod jest używany zarówno z kodu produkcyjnego, jak i z testów. Ale pamiętaj, po prostu dodaj elastyczność, której potrzebujesz, aby testy działały, nie mniej, nie więcej.

To właściwie stara mądrość. Dawno temu, zanim termin SOLID dostał popularne, ktoś powiedział mi, zanim spróbujemy napisać ponownie kod użytkową, powinniśmy napisać użytkowej kod. I nadal uważam, że to dobra rekomendacja.

Doktor Brown
źródło
23
Dodatkowe punkty sporne: Poczekaj, aż pojawią się 3 przypadki użycia, w których widzisz tę samą logikę, przed refaktoryzacją kodu do ponownego użycia. Jeśli zaczniesz refaktoryzację z 2 częściami, łatwo będzie skończyć w sytuacji, gdy zmieniające się wymagania lub nowy przypadek użycia doprowadzą do złamania dokonanej przez ciebie abstrakcji. Ograniczaj także refaktory do rzeczy z tym samym przypadkiem użycia: 2 komponenty mogą mieć ten sam kod, ale robią zupełnie inne rzeczy, a jeśli scalisz te komponenty, w końcu połączysz tę logikę, co może powodować problemy później.
Nzall
8
Generalnie się z tym zgadzam, ale wydaje mi się, że jest zbyt skoncentrowany na „jednorazowych” aplikacjach: piszesz kod, działa, dobrze. Istnieje jednak wiele aplikacji z „długim wsparciem”. Możesz napisać trochę kodu, a 2 lata później wymagania biznesowe zmienią się, więc musisz dostosować kod. Do tego czasu wiele innych kodów może zależeć od tego - w takim przypadku zasady SOLID ułatwią zmianę.
R. Schmitz
3
„Zanim spróbujemy napisać kod wielokrotnego użytku, powinniśmy napisać kod użyteczny” - bardzo mądrze!
Graham
10
To chyba warto zauważyć, że czeka, aż masz faktyczny use-case sprawi, że SOLID kod lepiej , ponieważ pracuje w hypotheticals jest bardzo trudne i jest prawdopodobne, aby mis-zgadnijcie co przyszłe potrzeby będzie. Nasz projekt ma wiele przypadków, w których rzeczy zostały zaprojektowane w taki sposób, aby były SOLIDNE i elastyczne na przyszłe potrzeby ... z wyjątkiem przyszłych potrzeb, które okazały się rzeczami, o których nikt nie myślał w tym czasie, więc oboje potrzebowaliśmy przebudować i mieliśmy dodatkową elastyczność wciąż nie potrzebował - który albo musiał zostać utrzymany w obliczu refaktoryzacji, albo złomowany.
KRyan
2
również zwykle będziesz musiał napisać testowalny kod, co zwykle oznacza, że ​​masz pierwszą warstwę abstrakcji, aby móc przejść od konkretnej implementacji do testowej.
Walfrat
49

Z mojego doświadczenia, pisząc aplikację, masz trzy możliwości:

  1. Napisz kod wyłącznie w celu spełnienia wymagań,
  2. Napisz ogólny kod, który przewiduje przyszłe wymagania, a także spełnia obecne wymagania,
  3. Napisz kod, który spełnia tylko bieżące wymagania, ale w sposób, który można później łatwo zmienić, aby spełnić inne potrzeby.

W pierwszym przypadku często występuje ścisły kod, który nie ma testów jednostkowych. Jasne, że napisanie jest szybkie, ale trudne do przetestowania. A właściwym jest królewski ból, aby zmienić go później, gdy zmienią się wymagania.

W drugim przypadku spędza się mnóstwo czasu, próbując przewidzieć przyszłe potrzeby. A nazbyt często te przewidywane przyszłe wymagania nigdy się nie spełniają. To wydaje się scenariusz, który opisujesz. Jest to strata wysiłku przez większość czasu i skutkuje niepotrzebnie złożonym kodem, który wciąż trudno zmienić, gdy pojawi się wymaganie, którego nie przewidywano.

Moim zdaniem celem jest ten ostatni przypadek. Użyj TDD lub podobnych technik, aby przetestować kod w miarę upływu czasu, a skończysz z luźno sprzężonym kodem, który jest łatwy do modyfikacji, ale wciąż szybki do napisania. Rzecz w tym, że postępując w ten sposób, naturalnie przestrzegasz wielu zasad SOLID: małych klas i funkcji; interfejsy i wstrzykiwane zależności. I pani Liskov jest również ogólnie szczęśliwa, ponieważ proste zajęcia z pojedynczymi obowiązkami rzadko są sprzeczne z jej zasadą zastępowania.

Jedynym aspektem SOLID, który tak naprawdę nie ma zastosowania, jest zasada otwartego / zamkniętego. Jest to ważne dla bibliotek i frameworków. W przypadku samodzielnej aplikacji, nie tyle. Naprawdę jest to przypadek pisania kodu zgodnego zSLID ”: łatwy do napisania (i odczytu), łatwy do przetestowania i łatwy w utrzymaniu.

David Arno
źródło
jedna z moich ulubionych odpowiedzi na tej stronie!
TheCatWhisperer
Nie jestem pewien, jak doszedłeś do wniosku, że 1) trudniej jest przetestować niż 3). Oczywiście trudniej jest wprowadzić zmiany, ale dlaczego nie możesz przetestować? Jeśli tak, to jedno oprogramowanie jest łatwiejsze do przetestowania pod kątem wymagań niż bardziej ogólne.
Pan Lister
@MrLister Dwa koziołki, 1. są trudniejsze do przetestowania niż 3., ponieważ definicja sugeruje, że nie jest napisana „w sposób, który można łatwo zmienić później, aby zaspokoić inne potrzeby”.
Mark Booth,
1
+0; IMVHO źle interpretujesz (choć w powszechny sposób) sposób działania „O” (otwarte-zamknięte). Zobacz np. Codeblog.jonskeet.uk/2013/03/15/… - nawet w małych bazach kodowych chodzi bardziej o samodzielne jednostki kodu (np. Klasy, moduły, pakiety itp.), Które można przetestować oddzielnie i dodać / usuwane w miarę potrzeby. Jednym z takich przykładów może być pakiet metod narzędziowych - niezależnie od sposobu ich pakowania, powinny one być „zamknięte”, tj. Być samodzielne i „otwarte”, tj. W jakiś sposób rozszerzalne.
vaxquis
BTW, nawet wujek Bob robi to w jednym punkcie: „Co oznacza [otwarte-zamknięte], to powinieneś starać się ustawić swój kod w takiej pozycji, aby gdy zachowanie zmienia się w oczekiwany sposób, nie musisz robić zamiatania zmiany we wszystkich modułach systemu. W idealnym przypadku możesz dodać nowe zachowanie, dodając nowy kod i zmieniając niewielki lub żaden stary kod. ” <- dotyczy to oczywiście nawet małych aplikacji, jeśli mają one być kiedykolwiek modyfikowane lub naprawiane (i, IMVHO, zazwyczaj tak jest, szczególnie w przypadku chichotu poprawek )
vaxquis
8

Perspektywa, którą masz, może być wypaczona przez osobiste doświadczenie. Jest to śliskie zbocze faktów, które są indywidualnie poprawne, ale wynikowe wnioskowanie nie jest, nawet jeśli na pierwszy rzut oka wydaje się poprawne.

  • Ramy mają większy zakres niż małe projekty.
  • Zła praktyka jest znacznie trudniejsza do rozwiązania w większych bazach kodów.
  • Budowanie frameworka (średnio) wymaga bardziej wykwalifikowanego programisty niż budowanie małego projektu.
  • Lepsi programiści stosują więcej dobrych praktyk (SOLID).
  • W rezultacie ramy mają większą potrzebę dobrych praktyk i zwykle są budowane przez programistów, którzy są bardziej doświadczeni w dobrych praktykach.

Oznacza to, że podczas interakcji z frameworkami i mniejszymi bibliotekami kod dobrej praktyki, z którym będziesz wchodzić w interakcje, będzie częściej znajdowany w większych frameworkach.

Ten błąd jest bardzo powszechny, np. Każdy lekarz, u którego byłem leczony, był arogancki. Dlatego dochodzę do wniosku, że wszyscy lekarze są aroganccy. Te błędy zawsze cierpią z powodu wyciągania wniosków na podstawie osobistych doświadczeń.

W twoim przypadku możliwe jest, że przeszedłeś dobrą praktykę w większych środowiskach, a nie w mniejszych bibliotekach. Twoje osobiste obserwacje nie są złe, ale są to niepotwierdzone dowody i nie mają uniwersalnego zastosowania.


2 tryby programowania - tworzenie mniej więcej dokładnie tego, co jest zadawane za pomocą wymagań i KISS (typowe programowanie), lub tworzenie bardzo ogólnej i wielokrotnego użytku logiki, usług itp., Które zapewniają elastyczność, jakiej mogą potrzebować inni programiści (programowanie w ramach frameworka)

Trochę to potwierdzasz. Pomyśl o tym, czym jest framework. To nie jest aplikacja. Jest to uogólniony „szablon”, którego inni mogą używać do tworzenia wszelkiego rodzaju aplikacji. Logicznie oznacza to, że struktura jest zbudowana w znacznie bardziej abstrakcyjnej logice, aby wszyscy mogli z niej korzystać.

Konstruktorzy frameworków nie są w stanie korzystać ze skrótów, ponieważ nawet nie wiedzą, jakie są wymagania kolejnych aplikacji. Zbudowanie frameworku z natury zachęca ich do używania kodu dla innych.

Twórcy aplikacji mają jednak możliwość kompromisu w zakresie wydajności logicznej, ponieważ koncentrują się na dostarczaniu produktu. Ich głównym celem nie jest działanie kodu, ale raczej doświadczenie użytkownika.

W przypadku frameworka końcowym użytkownikiem jest inny programista, który będzie wchodził w interakcje z Twoim kodem. Jakość kodu ma znaczenie dla użytkownika końcowego.
W przypadku aplikacji użytkownik końcowy nie jest programistą, który nie będzie wchodził w interakcje z Twoim kodem. Jakość twojego kodu nie ma dla nich znaczenia.

Właśnie dlatego architekci zespołu programistycznego często pełnią rolę strażników dobrych praktyk. Są o jeden krok od dostarczenia produktu, co oznacza, że ​​mają tendencję do obiektywnego patrzenia na kod, zamiast skupiania się na dostarczaniu samej aplikacji.


Jeśli dodasz te punkty wejścia do abstrakcji, czy naprawdę spełniasz wymagania użytkowników, czy tworzysz strukturę na podstawie istniejącej struktury i stosu technologicznego, aby ułatwić przyszłe dodawanie? W którym przypadku służysz interesom klienta lub programisty?

Jest to interesujący punkt i jest (z mojego doświadczenia) głównym powodem, dla którego ludzie nadal próbują uzasadnić unikanie dobrych praktyk.

Podsumowując poniższe punkty: Pominięcie dobrej praktyki może być uzasadnione tylko wtedy, gdy twoje wymagania (jak obecnie znane) są niezmienne i nigdy nie będzie żadnych zmian / dodatków do bazy kodu. Ostrzeżenie o spoilerze: rzadko się to zdarza.
Na przykład, gdy piszę 5-minutową aplikację konsoli do przetwarzania określonego pliku, nie stosuję dobrych praktyk. Ponieważ zamierzam korzystać z aplikacji tylko dzisiaj i nie będzie trzeba jej aktualizować w przyszłości (łatwiej byłoby napisać inną aplikację, gdybym jej potrzebował ponownie).

Załóżmy, że możesz tandetnie zbudować aplikację w 4 tygodnie i poprawnie ją zbudować w 6 tygodni. Na pierwszy rzut oka tandetne budowanie wydaje się lepsze. Klient otrzymuje aplikację szybciej, a firma musi poświęcać mniej czasu na płace programistów. Wygrana / wygrana, prawda?

Jest to jednak decyzja podjęta bez wybiegania w przyszłość. Z powodu jakości bazy kodu dokonanie poważnej zmiany w tandetnie zbudowanym zajmie 2 tygodnie, a wprowadzenie tych samych zmian w poprawnie zbudowanej zajmie 1 tydzień. W przyszłości może pojawić się wiele z tych zmian.

Co więcej, istnieje tendencja do nieoczekiwanych zmian, które wymagają więcej pracy, niż początkowo sądzono, w tandetnie zbudowanych bazach kodu, co prawdopodobnie skraca czas programowania do trzech tygodni zamiast dwóch.

A także tendencja do marnowania czasu na poszukiwanie błędów. Dzieje się tak często w projektach, w których rejestrowanie zostało zignorowane z powodu ograniczeń czasowych lub zwykłej niechęci do jego wdrożenia, ponieważ bezmyślnie pracujesz przy założeniu, że produkt końcowy będzie działał zgodnie z oczekiwaniami.

To nawet nie musi być poważną aktualizacją. U mojego obecnego pracodawcy widziałem kilka projektów, które zostały zbudowane szybko i brudno, a kiedy najmniejszy błąd / zmiana musiała zostać wykonana z powodu nieporozumienia w wymaganiach, które prowadziły do ​​reakcji łańcuchowej z koniecznością refaktoryzacji moduł po module . Niektóre z tych projektów upadały (pozostawiając nie do utrzymania bałagan), zanim nawet wydali swoją pierwszą wersję.

Decyzje skrótowe (szybkie i nieprzyzwoite programowanie) są korzystne tylko wtedy, gdy można jednoznacznie zagwarantować, że wymagania są dokładnie poprawne i nigdy nie trzeba ich zmieniać. Z mojego doświadczenia nigdy nie spotkałem się z projektem, w którym to prawda.

Inwestowanie dodatkowego czasu w dobrą praktykę to inwestowanie w przyszłość. Przyszłe błędy i zmiany będą o wiele łatwiejsze, gdy istniejąca baza kodów będzie oparta na dobrych praktykach. Będzie już wypłacał dywidendy po wprowadzeniu tylko dwóch lub trzech zmian.

Flater
źródło
1
To dobra odpowiedź, ale powinienem wyjaśnić, że nie mówię, że porzucamy dobre praktyki, ale jaki poziom „dobrych praktyk” stosujemy? Czy dobrą praktyką jest wyodrębnianie ORM w każdym projekcie, ponieważ „być może” będziesz musiał później zamienić go na inny? Nie sądzę, istnieją pewne poziomy sprzężenia, które jestem gotów zaakceptować (tzn. Jestem związany z wybraną strukturą, językiem, ORM, bazą danych). Jeśli podążamy za SOLIDEM w jego ekstremistycznym stopniu, to czy naprawdę po prostu wdrażamy naszą własną strukturę nad wybranym stosem?
Igneous01,
Odmawiasz doświadczenia OP jako „błędnego”. Nie konstruktywne.
max630
@ max630 Nie zaprzeczam. Sporo czasu poświęciłem na wyjaśnienie, dlaczego obserwacje OP są ważne.
Flater
1
@ Igneous01 SOLID nie jest platformą. SOLID jest abstrakcją, którą częściej spotyka się w frameworku. W przypadku implementacji dowolnego rodzaju abstrakcji (w tym SOLID) zawsze istnieje szereg zasadności. Nie możesz po prostu abstrakcji dla samej abstrakcji, spędziłbyś całe wieki wymyślając kod, który jest tak nadgeneralizowany, że trudno go śledzić. Tylko streszczenie, co do czego masz uzasadnione podejrzenia, przyda ci się w przyszłości. Nie wpadaj jednak w pułapkę zakładania, że ​​jesteś związany np. Z bieżącym serwerem bazy danych. Nigdy nie wiadomo, która nowa baza danych zostanie wydana jutro.
Flater
@ Igneous01 Innymi słowy, masz dobry pomysł, nie chcąc abstrakcji wszystkiego, ale mam wrażenie, że pochylasz się tak lekko za daleko w tym kierunku. Bardzo często programiści zakładają, że bieżące wymagania są ustalone, a następnie podejmują decyzje architektoniczne na podstawie tego (życzeniowego) założenia.
Flater
7

W jaki sposób SOLID zamienia prosty kod w kod frameworka? W żadnym wypadku nie jestem stanem na SOLID, ale tak naprawdę nie jest oczywiste, co masz na myśli.

  • Kiss istotą S odpowiedzialności Ingle zasadą.
  • W O pen / Closed Principle nie ma nic (przynajmniej tak rozumiem - patrz Jon Skeet ), co byłoby sprzeczne z pisaniem kodu, aby zrobić jedną rzecz dobrze. (W rzeczywistości im bardziej ścisły jest kod, tym ważniejsza staje się część „zamknięta”).
  • L iskov Zmiana Zasada nie mówi, trzeba pozwolić ludziom podklasy swoich klas. Mówi, że jeśli jesteś podklasy swoje zajęcia, swoje podklasy powinny spełniać umowy o ich superklas. To po prostu dobry projekt OO. (A jeśli nie masz żadnych podklas, nie ma to zastosowania).
  • KISS jest również istotą I nterface Segregacja zasady.
  • D ependency Inversion Zasada jest tylko jedna widzę zdalnie stosowania, ale myślę, że to szeroko rozumiany i przesadzone. Nie oznacza to, że musisz wstrzyknąć wszystko za pomocą Guice lub Spring. Oznacza to po prostu, że w razie potrzeby powinieneś streścić i nie zależeć od szczegółów implementacji.

Przyznaję, że sam nie myślę w kategoriach SOLID, ponieważ wymyśliłem szkoły programowania Gang of Four i Josh Bloch , a nie szkołę Boba Martina. Ale naprawdę uważam, że jeśli myślisz „SOLID” = „dodawanie kolejnych warstw do stosu technologicznego”, źle to czytasz.


PS Nie sprzedawaj korzyści „lepszego UX dla programisty” w skrócie. Kod spędza większość swojego życia na utrzymaniu. Deweloper to ty .

David Moles
źródło
1
Jeśli chodzi o SRP - można argumentować, że każda klasa z konstruktorem narusza SRP, ponieważ można przenieść tę odpowiedzialność na fabrykę. Jeśli chodzi o OCP - jest to naprawdę problem na poziomie frameworku, ponieważ po opublikowaniu interfejsu do konsumpcji do użytku zewnętrznego nie można go modyfikować. Jeśli interfejs jest używany tylko w projekcie, możliwa jest zmiana umowy, ponieważ masz uprawnienia do zmiany umowy w ramach własnego kodu. W odniesieniu do ISP - można argumentować, że interfejs powinien być zdefiniowany dla każdej akcji (zachowując w ten sposób SRP) i dotyczy zewnętrznych użytkowników.
Igneous01,
3
1) można, ale wątpię, by ktoś, kogo warto kiedykolwiek słuchać. 2) możesz być zaskoczony, jak szybko jeden projekt może osiągnąć rozmiar, który dowolna modyfikacja wewnętrznych interfejsów staje się złym pomysłem. 3) patrz zarówno 1), jak i 2). Wystarczy powiedzieć, że myślę, że za dużo czytasz we wszystkich trzech zasadach. Ale komentarze nie są tak naprawdę miejscem na rozwiązywanie tych argumentów; Sugeruję, abyś zadał każde z nich jako osobne pytanie i zobaczył, jakie odpowiedzi otrzymujesz.
David Moles,
4
@ Igneous01 Korzystając z tej logiki, równie dobrze możesz porzucić gettery i settery, ponieważ możesz stworzyć osobną klasę dla każdego setera zmiennych i jedną dla każdego gettera. IE: class A{ int X; int Y; } class A_setX{ f(A a, int N) { a.X = N; }} class A_getX{ int f(A a) { return X; }} class A_setY ... etc.Myślę, że patrzysz na to ze zbyt meta punktu widzenia w odniesieniu do roszczenia fabryki. Inicjalizacja nie jest aspektem problemu z domeną.
Aaron
@Aaron This. Ludzie mogą używać SOLID do robienia złych argumentów, ale to nie znaczy robienia złych rzeczy = „podążanie za SOLID”.
David Moles,