Ile wzorów i poziomów abstrakcji jest niezbędnych? [Zamknięte]

29

Jak mogę stwierdzić, że moje oprogramowanie ma zbyt dużo abstrakcji i zbyt wiele wzorców projektowych, lub odwrotnie, skąd mam wiedzieć, czy powinno być ich więcej?

Programiści, z którymi pracuję, programują inaczej w tych kwestiach.

Niektóre wykonują abstrakcję każdej małej funkcji, w miarę możliwości używają wzorców projektowych i unikają nadmiarowości za wszelką cenę.

Inni, w tym ja, starają się być bardziej pragmatyczni i piszą kod, który nie pasuje idealnie do każdego wzorca projektowego, ale jest znacznie szybszy do zrozumienia, ponieważ stosuje się mniej abstrakcji.

Wiem, że to jest kompromis. Skąd mam wiedzieć, kiedy w projekcie jest wystarczająco dużo abstrakcji i skąd mam wiedzieć, że potrzebuje więcej?

Przykład, gdy ogólna warstwa buforująca jest zapisywana przy użyciu Memcache. Czy naprawdę potrzebujemy Memcache, MemcacheAdapter, MemcacheInterface, AbstractCache, CacheFactory, CacheConnector, ... czy jest to łatwiejsze do utrzymania i nadal dobry kod przy użyciu tylko połowa z tych klas?

Znaleziono to na Twitterze:

wprowadź opis zdjęcia tutaj

( https://twitter.com/rawkode/status/875318003306565633 )

Daniel W.
źródło
58
Jeśli traktujesz wzorce projektowe jako rzeczy, które wyciągasz z wiadra i używasz do składania programów, używasz ich zbyt wiele.
Blrfl
5
Możesz pomyśleć o wzorcach projektowych, takich jak wzorce mowy, których ludzie używają. Ponieważ w pewnym sensie idiomy, metafory itp. Są wzorcami projektowymi. Jeśli używasz idiomu w każdym zdaniu ... to prawdopodobnie zbyt często. Mogą jednak pomóc w wyjaśnieniu myśli i zrozumieniu czegoś, co w innym przypadku byłoby długą ścianą prozy. Naprawdę nie ma właściwego sposobu, aby odpowiedzieć „jak często powinienem używać metafor?” - to zależy od oceny autora.
Prime
8
Nie ma możliwości, aby jedna odpowiedź SE mogła odpowiednio obejmować ten temat. Zajmuje to dosłownie lata doświadczenia i mentoringu. Jest to wyraźnie zbyt szerokie.
jpmc26
5
Postępuj zgodnie z podstawową zasadą projektowania w branży lotniczej: „Uprość i dodaj więcej lekkości”. Kiedy odkryjesz, że najlepszym sposobem na naprawienie błędu jest po prostu usunięcie kodu zawierającego błąd, ponieważ nadal nie robi nic użytecznego, nawet jeśli nie zawiera błędów, zaczynasz poprawiać projekt!
alephzero

Odpowiedzi:

52

Ile składników jest potrzebnych do posiłku? Ile części potrzebujesz, aby zbudować pojazd?

Wiesz, że masz za mało abstrakcji, gdy niewielka zmiana implementacji prowadzi do kaskady zmian w całym kodzie. Odpowiednie abstrakcje pomogłyby wyodrębnić część kodu, którą należy zmienić.

Wiesz, że masz zbyt dużo abstrakcji, gdy niewielka zmiana interfejsu prowadzi do kaskady zmian w całym kodzie, na różnych poziomach. Zamiast zmieniać interfejs między dwiema klasami, modyfikujesz dziesiątki klas i interfejsów, aby dodać właściwość lub zmienić typ argumentu metody.

Poza tym naprawdę nie ma sposobu, aby odpowiedzieć na pytanie, podając numer. Liczba abstrakcji nie będzie taka sama w zależności od projektu, od języka do języka, a nawet od jednego programisty do drugiego.

Arseni Mourzenko
źródło
28
Jeśli masz tylko dwa interfejsy i setki klas implementujących je, zmiana interfejsów prowadziłaby do kaskady zmian, ale to nie znaczy, że jest zbyt wiele abstrakcji, ponieważ masz tylko dwa interfejsy.
Tulains Córdova
Liczba abstrakcji nie będzie nawet taka sama dla różnych części tego samego projektu!
T. Sar - Przywróć Monikę
Wskazówka: zmiana z Memcache na inny mechanizm buforowania (Redis?) Jest zmianą implementacyjną .
Ogre Psalm33
Twoje dwie zasady (wytyczne, jakkolwiek chcesz je nazwać) nie działają, jak pokazują Tulains. Są również żałośnie niekompletne, nawet jeśli tak zrobili. Reszta postu nie zawiera odpowiedzi, mówiąc niewiele więcej niż nie jesteśmy w stanie udzielić odpowiedzi w rozsądnym zakresie. -1
jpmc26
Chciałbym twierdzą, że w przypadku dwóch interfejsów i setek klas wprowadzających je, to całkiem możliwe, że nadmiernie swoje abstrakcje. Z pewnością widziałem to w projektach, które ponownie wykorzystują bardzo niejasną abstrakcję w wielu miejscach ( interface Doer {void prepare(); void doIt();}), a refaktoryzacja staje się bolesna, gdy ta abstrakcja już nie pasuje. Kluczową częścią odpowiedzi jest to, że test ma zastosowanie, gdy abstrakcja musi się zmienić - jeśli nigdy się nie zmienia, nigdy nie powoduje bólu.
James_pic
24

Problem z wzorami projektowymi można podsumować przysłowiem „gdy trzymasz młotek, wszystko wygląda jak gwóźdź”. Czynność zastosowania wzorca projektowego nie poprawia twojego programu. W rzeczywistości argumentowałbym, że tworzysz bardziej skomplikowany program, jeśli dodajesz wzorzec projektowy. Pozostaje pytanie, czy dobrze wykorzystujesz wzór, czy nie, i to jest sedno pytania: „Kiedy mamy zbyt dużo abstrakcji?”.

Jeśli tworzysz interfejs i abstrakcyjną superklasę dla jednej implementacji, dodałeś do projektu dwa dodatkowe komponenty, które są zbędne i niepotrzebne. Celem zapewnienia interfejsu jest możliwość równego obsługiwania go w całym programie bez wiedzy o tym, jak to działa. Celem abstrakcyjnej superklasy jest zapewnienie podstawowego zachowania dla implementacji. Jeśli masz tylko jedną implementację, otrzymujesz wszystkie interfejsy komplikacji i klasy abstact, które nie zapewniają żadnych korzyści.

Podobnie, jeśli używasz wzorca fabrycznego i okazuje się, że rzucasz klasę, aby użyć funkcji dostępnych tylko w superklasie, wzorzec fabryczny nie dodaje żadnych korzyści do twojego kodu. Dodałeś tylko dodatkową klasę do swojego projektu, której można było uniknąć.

TL; DR Chodzi mi o to, że celem abstrakcji nie jest sama w sobie abstrakcja. Służy to bardzo praktycznemu celowi w twoim programie, a zanim zdecydujesz się użyć wzorca projektowego lub utworzyć interfejs, powinieneś zadać sobie pytanie, czy dzięki temu program jest łatwiejszy do zrozumienia pomimo dodatkowej złożoności lub program jest bardziej niezawodny pomimo dodatkowej złożoności (najlepiej obu). Jeśli odpowiedź jest przecząca lub może, poświęć kilka minut, aby zastanowić się, dlaczego chcesz to zrobić, a jeśli może być to zrobione lepiej, bez konieczności dodawania abstrakcji do kodu.

Neil
źródło
Analogia młota byłaby problemem znającym tylko jeden wzór projektowy. Wzory projektowe powinny stworzyć cały zestaw narzędzi do wyboru i zastosowania w razie potrzeby. Nie wybieraj młota, aby złamać orzecha.
Pete Kirkham,
@ PeteteKirkham To prawda, ale nawet cała gama wzorów projektowych do Twojej dyspozycji może nie być odpowiednio dopasowana do konkretnego problemu. Jeśli młot nie nadaje się najlepiej do złamania nakrętki i nie jest też śrubokrętem, ani też nie jest miarą taśmy, ponieważ brakuje ci młotka, co nie czyni młota odpowiednim narzędziem do pracy, po prostu sprawia, że to najbardziej odpowiednie z dostępnych narzędzi. Nie oznacza to jednak, że powinieneś używać młota do łamania orzechów. Cholera, jeśli jesteśmy szczerzy, tak naprawdę potrzebowałbyś dziadka do orzechów, a nie młotka ...
Neil
Chcę armii wyszkolonych wiewiórek do mojego łupania orzechów.
icc97
6

TL: DR;

Nie sądzę, że istnieje „niezbędna” liczba poziomów abstrakcji, poniżej których jest za mało lub powyżej, których jest za dużo. Podobnie jak w przypadku grafiki, dobry projekt OOP powinien być niewidoczny i należy go uważać za pewnik. Zły projekt zawsze wystaje jak obolały kciuk.

Długa odpowiedź

Najprawdopodobniej nigdy nie dowiesz się, na jakim poziomie abstrakcji budujesz.

Większość poziomów abstrakcji jest dla nas niewidoczna i przyjmujemy je za pewnik.

To rozumowanie prowadzi mnie do tego wniosku:

Jednym z głównych celów abstrakcji jest oszczędzanie programiście konieczności ciągłego myślenia o działaniu systemu. Jeśli projekt zmusza Cię do zbyt dużej wiedzy o systemie, aby coś dodać, prawdopodobnie jest za mało abstrakcji. Myślę, że zła abstrakcja (zły projekt, anemiczny projekt lub nadmierna inżynieria) może również zmusić cię do zbyt dużej wiedzy, aby coś dodać. W jednym ekstremum mamy projekt oparty na boskiej klasie lub grupie DTO, w drugim ekstremum mamy pewne ramy OR / persistance, które zmuszają cię do przeskakiwania przez niezliczone obręcze, aby uzyskać cześć świata. Oba przypadki wymuszają zbytnią wiedzę.

Zła abstrakcja przylega do dzwonu Gaussa, ponieważ po przejechaniu słodkiego miejsca zaczyna ci przeszkadzać. Z drugiej strony dobra abstrakcja jest niewidoczna i nie może być jej zbyt wiele, ponieważ nie zauważasz jej. Zastanów się, ile warstw interfejsów API, protokołów sieciowych, bibliotek, bibliotek systemu operacyjnego, systemów plików, warstw harware itp. Tworzona jest aplikacja i jest dla niej oczywistością.

Innym głównym celem abstrakcji jest podział na przedziały, więc błędy nie przenikają poza określony obszar, podobnie jak podwójny kadłub i oddzielne zbiorniki zapobiegają całkowitemu zatopieniu statku, gdy część kadłuba ma dziurę. Jeśli modyfikacje kodu powodują błędy w pozornie niepowiązanych obszarach, istnieje duże prawdopodobieństwo, że abstrakcja jest zbyt mała.

Tulains Córdova
źródło
2
„Najprawdopodobniej nigdy nie dowiesz się, ile poziomów abstrakcji budujesz.” - W rzeczywistości sedno abstrakcji polega na tym, że nie wiesz, w jaki sposób jest ona implementowana, a JA nie wiesz (i nie możesz ) wiedzieć, ile poziomów abstrakcji ukrywa.
Jörg W Mittag
4

Wzorce projektowe są po prostu powszechnymi rozwiązaniami problemów. Ważne jest, aby znać wzorce projektowe, ale są to tylko objawy dobrze zaprojektowanego kodu (dobry kod wciąż może być pozbawiony grupy czterech wzorców projektowych), a nie przyczyna.

Abstrakcje są jak ogrodzenia. Pomagają rozdzielić regiony programu na testowalne i wymienne części (wymagania dotyczące tworzenia niestabilnego, niesztywnego kodu). I podobnie jak ogrodzenia:

  • Chcesz abstrakcje w naturalnych punktach interfejsu, aby zminimalizować ich rozmiar.

  • Nie chcesz ich zmieniać.

  • Chcesz, aby rozdzielili rzeczy, które mogą być niezależne.

  • Posiadanie jednego w niewłaściwym miejscu jest gorsze niż brak go.

  • Nie powinny mieć dużych przecieków .

dlasalle
źródło
4

Refaktoryzacja

Do tej pory nie widziałem słowa „refaktoryzacja”. Więc zaczynamy:

Zapraszam do wdrożenia nowej funkcji tak bezpośrednio, jak to możliwe. Jeśli masz tylko jedną, prostą klasę, prawdopodobnie nie potrzebujesz do tego interfejsu, nadklasy, fabryki itp.

Jeśli zauważysz, że rozwijasz klasę w taki sposób, że staje się ona zbyt gruba, to nadszedł czas, aby ją rozerwać. W tym czasie warto zastanowić się, jak powinieneś to zrobić.

Wzory są narzędziem umysłu

Wzory, a ściślej książka „Wzory projektowe” autorstwa gangu czterech osób, są świetne, między innymi, ponieważ budują język, w którym programiści mogą się zastanawiać i mówić. Łatwo jest powiedzieć „obserwator”, „fabryka” lub „fasada” i wszyscy od razu dokładnie wiedzą , co to znaczy.

Dlatego uważam, że każdy programista powinien mieć wiedzę na temat przynajmniej wzorców z oryginalnej książki, aby móc mówić o koncepcjach OO bez konieczności wyjaśniania podstaw. Czy powinieneś używać wzorów za każdym razem, gdy pojawi się taka możliwość? Najprawdopodobniej nie.

Biblioteki

Biblioteki są prawdopodobnie jedynym obszarem, w którym może występować błąd po zbyt wielu wyborach opartych na wzorach zamiast za mało. Zmiana czegoś z „grubej” klasy na coś bardziej opartego na wzorcach (zwykle oznacza to więcej i mniejsze klasy) radykalnie zmieni interfejs; i to jest jedna rzecz, której zwykle nie chcesz zmieniać w bibliotece, ponieważ jest to jedyna rzecz, która naprawdę interesuje użytkownika twojej biblioteki. Nie dbają o to, jak sobie radzisz z wewnętrzną funkcjonalnością, ale bardzo dbają, jeśli będą musieli ciągle zmieniać swój program, gdy robisz nową wersję z nowym API.

AnoE
źródło
2

Punktem abstrakcji powinna być przede wszystkim wartość, jaką przynosi konsument abstrakcji, tj. Klient abstrakcji, inni programiści, a często ty sam.

Jeśli jako klient, który spożywa abstrakty, musisz wymieszać i dopasować wiele różnych abstrakcji, aby wykonać zadanie programistyczne, to potencjalnie istnieje zbyt wiele abstrakcji.

Idealnie, warstwowanie powinno łączyć szereg niższych abstrakcji i zastępować je prostą abstrakcją wyższego poziomu, z której konsumenci mogą korzystać bez konieczności zajmowania się którąkolwiek z tych abstrakcji. Jeśli mają do czynienia z abstrakcyjnymi bazami, wówczas warstwa przecieka (ponieważ jest niekompletna). Jeśli konsument ma do czynienia z zbyt wieloma różnymi abstrakcjami, być może brakuje warstw.

Po rozważeniu wartości abstrakcji dla zużywających się programistów, możemy przejść do oceny i rozważyć implementację, taką jak DRY-ness.

Tak, chodzi przede wszystkim o ułatwienie konserwacji, ale najpierw powinniśmy wziąć pod uwagę trudną sytuację naszych klientów, zapewniając wysokiej jakości abstrakty i warstwy, a następnie rozważyć ułatwienie własnej konserwacji pod względem aspektów implementacyjnych, takich jak unikanie redundancji.


Przykład, gdy ogólna warstwa buforująca jest zapisywana przy użyciu Memcache. Czy naprawdę potrzebujemy Memcache, MemcacheAdapter, MemcacheInterface, AbstractCache, CacheFactory, CacheConnector, ... czy jest to łatwiejsze w utrzymaniu i nadal dobrym kodzie, gdy używa się tylko połowy tych klas?

Musimy spojrzeć na perspektywę klienta, a jeśli jego życie jest łatwiejsze, to dobrze. Jeśli ich życie jest bardziej złożone, jest źle. Może się jednak zdarzyć, że brakuje warstwy, która owija te rzeczy w coś prostego w użyciu. Wewnętrznie mogą one znacznie poprawić utrzymanie wdrożenia. Jednak, jak podejrzewasz, możliwe jest również, że jest on tylko przerobiony.

Erik Eidt
źródło
2

Abstrakcja ma na celu ułatwienie zrozumienia kodu. Jeśli warstwa abstrakcji sprawi, że wszystko będzie bardziej zagmatwane - nie rób tego.

Celem jest użycie prawidłowej liczby abstrakcji i interfejsów w celu:

  • zminimalizować czas programowania
  • zmaksymalizować łatwość konserwacji kodu

Streszczenie tylko w razie potrzeby

  1. Kiedy odkryjesz, że piszesz super klasę
  2. Kiedy pozwoli to na znaczne ponowne użycie kodu
  3. Jeśli abstrakcja sprawi, że kod stanie się znacznie wyraźniejszy i łatwiejszy do odczytania

Nie streszczaj kiedy

  1. Takie postępowanie nie przyniesie korzyści w zakresie ponownego użycia kodu ani przejrzystości
  2. Dzięki temu kod będzie znacznie dłuższy / bardziej złożony, bez żadnych korzyści

Kilka przykładów

  • Jeśli będziesz mieć tylko jedną pamięć podręczną w całym programie, nie abstrakuj, chyba że uważasz, że prawdopodobnie skończysz z nadklasą
  • Jeśli masz trzy różne typy buforów, użyj wspólnej abstrakcji interfejsu dla nich wszystkich
sdfgeoff
źródło
2

Myślę, że może to być kontrowersyjna meta-odpowiedź, i jestem trochę spóźniony na imprezę, ale myślę, że bardzo ważne jest, aby wspomnieć o tym tutaj, ponieważ myślę, że wiem, skąd pochodzisz.

Problem ze sposobem używania wzorców projektowych polega na tym, że kiedy są nauczane, przedstawiają taki przypadek:

Masz ten konkretny scenariusz. Uporządkuj swój kod w ten sposób. Oto elegancki, ale nieco wymyślony przykład.

Problem polega na tym, że kiedy zaczynasz robić prawdziwą inżynierię, rzeczy nie są już takie proste. Wzorzec projektowy, o którym czytasz, nie do końca pasuje do problemu, który próbujesz rozwiązać. Nie wspominając o tym, że biblioteki, których używasz, całkowicie naruszają wszystko, co podano w tekście, wyjaśniając te wzorce, każda na swój sposób. W rezultacie kod, który piszesz, „wydaje się niewłaściwy” i zadajesz takie pytania.

Oprócz tego chciałbym zacytować Andrei Alexandrescu, mówiąc o inżynierii oprogramowania, który stwierdza:

Inżynieria oprogramowania, być może bardziej niż jakakolwiek inna dziedzina inżynierii, wykazuje bogatą różnorodność: możesz zrobić to samo na wiele poprawnych sposobów, a nieskończone niuanse między dobrem a złem.

Być może jest to trochę przesada, ale myślę, że to doskonale wyjaśnia dodatkowy powód, dla którego możesz czuć się mniej pewnie w swoim kodzie.

W takich czasach proroczy głos Mike Acton, lider silnika gry w Insomniac, krzyczy mi w głowie:

ZNAJ SWOJE DANE

Mówi o wejściach do twojego programu i pożądanych wyjściach. A potem jest ten klejnot Freda Brooksa z Miesiąca Mitycznego Człowieka:

Pokażcie mi swoje schematy blokowe i ukryjcie swoje stoły, a będę nadal mistyfikowany. Pokaż mi swoje tabele, a zwykle nie potrzebuję twoich schematów blokowych; będą oczywiste.

Więc gdybym był tobą, uzasadniałbym mój problem na podstawie mojego typowego przypadku wejściowego i tego, czy osiąga on pożądany prawidłowy wynik. I zadawaj takie pytania:

  • Czy dane wyjściowe z mojego programu są prawidłowe?
  • Czy jest produkowany wydajnie / szybko dla mojego najpopularniejszego przypadku wejściowego?
  • Czy mój kod jest wystarczająco łatwy do lokalnego uzasadnienia, zarówno dla mnie, jak i moich kolegów z drużyny? Jeśli nie, to czy mogę to uprościć?

Kiedy to zrobisz, pytanie „ile warstw abstrakcji lub wzorów jest potrzebnych” staje się znacznie łatwiejsze do odpowiedzi. Ile warstw abstrakcji potrzebujesz? Tyle, ile jest to konieczne do osiągnięcia tych celów, i nie więcej. „Co z wzorami projektowymi? Nie użyłem żadnych!” Cóż, jeśli powyższe cele zostały osiągnięte bez bezpośredniego zastosowania wzoru, to w porządku. Uruchom to i przejdź do następnego problemu. Zacznij od swoich danych, a nie od kodu.

nasser-sh
źródło
2

Architektura oprogramowania wymyśla języki

Z każdą warstwą oprogramowania tworzysz język, w którym ty (lub twoi współpracownicy) chcesz wyrazić swoje rozwiązanie wyższej warstwy (więc wrzucę w moim poście kilka analogów języka naturalnego). Twoi użytkownicy nie chcą spędzać lat na nauce czytania lub pisania tego języka.

Ten widok pomaga mi w podejmowaniu decyzji dotyczących kwestii architektonicznych.

Czytelność

Język ten powinien być łatwo zrozumiały (dzięki czemu kod następnej warstwy będzie czytelny). Kod jest odczytywany znacznie częściej niż pisany.

Jedna koncepcja powinna być wyrażona jednym słowem - jedna klasa lub interfejs powinien ujawniać koncepcję. (Języki słowiańskie zwykle mają dwa różne słowa dla jednego angielskiego czasownika, więc musisz nauczyć się podwójnego słownictwa. Wszystkie języki naturalne używają pojedynczych słów dla wielu pojęć).

Koncepcje, które ujawniasz, nie powinny zawierać niespodzianek. Są to głównie konwencje nazewnictwa, takie jak metody get i set itp. A wzorce projektowe mogą pomóc, ponieważ zapewniają standardowy wzorzec rozwiązania, a czytelnik widzi „OK, dostaję obiekty z fabryki” i wie, co to znaczy. Ale jeśli po prostu utworzenie konkretnej klasy spełnia swoje zadanie, wolałbym to.

Użyteczność

Język powinien być łatwy w użyciu (ułatwiając sformułowanie „poprawnych zdań”).

Jeśli wszystkie te klasy / interfejsy MemCache staną się widoczne dla następnej warstwy, tworzy to stromą krzywą uczenia się dla użytkownika, dopóki nie zrozumie, kiedy i gdzie użyć które z tych słów dla pojedynczej koncepcji pamięci podręcznej.

Udostępnienie tylko niezbędnych klas / metod ułatwia użytkownikowi znalezienie tego, czego potrzebuje (patrz cytat DocBrowns Antoine de Saint-Exupery). Ujawnienie interfejsu zamiast klasy implementacyjnej może to ułatwić.

Jeśli udostępnisz funkcjonalność, w której można zastosować ustalony wzorzec projektowy, lepiej postępować zgodnie z tym wzorcem projektowym niż wymyślić coś innego. Twój użytkownik zrozumie interfejsy API zgodne z wzorcem projektowym łatwiej niż jakaś inna koncepcja (jeśli znasz włoski, hiszpański będzie dla ciebie łatwiejszy niż chiński).

Podsumowanie

Wprowadź abstrakcje, jeśli ułatwia to korzystanie (i jest warte narzutu utrzymania zarówno abstrakcji, jak i implementacji).

Jeśli twój kod ma (nietrywialne) pod-zadanie, rozwiąż je „w oczekiwany sposób”, tj. Postępuj zgodnie z odpowiednim wzorcem projektowym zamiast wymyślać inny typ koła.

Ralf Kleberhoff
źródło
1

Ważną rzeczą do rozważenia jest to, ile konsumencki kod, który faktycznie obsługuje logikę biznesową, powinien wiedzieć o tych klasach związanych z buforowaniem. Idealnie, twój kod powinien dbać tylko o obiekt pamięci podręcznej, który chce utworzyć, i być może fabrykę, która utworzy ten obiekt, jeśli metoda konstruktora nie jest wystarczająca.

Liczba użytych wzorców lub poziom dziedziczenia nie są zbyt ważne, o ile każdy poziom można uzasadnić innym programistom. Stwarza to nieformalny limit, ponieważ każdy dodatkowy poziom jest trudniejszy do uzasadnienia. Ważniejszą częścią jest to, na ile poziomów abstrakcji wpływają zmiany wymagań funkcjonalnych lub biznesowych. Jeśli możesz zmienić tylko jeden poziom dla pojedynczego wymagania, prawdopodobnie nie jesteś zbyt abstrakcyjny lub źle wyodrębniony, jeśli zmienisz ten sam poziom dla wielu niepowiązanych zmian, prawdopodobnie nie jesteś abstrakcyjny i musisz dalej rozdzielać obawy.

Ryathal
źródło
-1

Po pierwsze, cytat na Twitterze jest fałszywy. Nowi programiści muszą opracować model, abstrakcje zwykle pomagają im „uzyskać obraz”. Pod warunkiem, że abstrakcje mają sens.

Po drugie, twoim problemem nie jest zbyt wiele lub zbyt mało abstrakcji, najwyraźniej nikt nie może decydować o tych sprawach. Nikt nie jest właścicielem kodu, żaden plan / projekt / filozofia nie jest zaimplementowany, każdy następny facet może zrobić wszystko, do diabła, co wydaje się odpowiednie w tej chwili. Niezależnie od tego, jaki styl wybierzesz, powinien to być jeden.

Martin Maat
źródło
2
Powstrzymajmy się od lekceważenia tych doświadczeń jako „fałszywych”. Zbyt wiele abstrakcji to prawdziwy problem. Niestety ludzie dodają abstrakcję z góry, ponieważ „najlepsza praktyka” zamiast rozwiązać prawdziwy problem. Ponadto nikt nie może decydować „o tych sprawach” ... ludzie opuszczają firmy, ludzie dołączają, nikt nie bierze na własność ich błota.
Rawkode