Dlaczego programy "enterprise" muszą być tak kosmicznie przekombinowane?

Dlaczego programy "enterprise" muszą być tak kosmicznie przekombinowane?

Wątek przeniesiony 2021-10-09 12:07 z Flame przez Shalom.

CR
  • Rejestracja:około 6 lat
  • Ostatnio:około godziny
  • Postów:112
17

Byłem już w iluś projektach, ale w większości były stosunkowo niewielkie. Staraliśmy się, żeby kod był czysty i czytelny - pisaliśmy "dla siebie".
Ostatnio trafiłem do takiego "korpo-projektu" zrobionego przez jakichś szaleńców, którzy naczytali się 10000 książek o wzorcach projektowych, i oczywiście nie po to, żeby teraz nie wciskać tych wszystkich wzorców wszędzie, niezależnie czy ma to jakikolwiek sens czy nie. Nie można zrobić

Kopiuj
int sum = 2 + 3;

tylko trzeba

Kopiuj
Integer a = IntegerBuilder
  .fromPrimitiveInt(2)
  .withSign('+')
  .build();
Integer b = IntegerBuilder
  .fromPrimitiveInt(3)
  .withSign('+')
  .build();
Integer sum = OperationResultFactory
  .createResult()
  .withOperationType(operationUtils.getOperation('addition'))
  .withNumbers(ArrayOfNumbersHandler.getNumbersFromNumberListWrapper(ArrayOfNumbersHandler.createArrayOfNumbersFromIntegers(a, b)
  .doWhateverOtherUnnecessaryBsICouldThinkOf();

??
To jest jakieś kompletne szaleństwo. Nawciskane warstw abstrakcji, które nie rozwiązują żadnych problemów, tylko tworzą nowe. Chcesz zobaczyć, co się dzieje, np. jak wstawisz nowy rekord typu User do bazy? Nie wystarczy, że zerkniesz do UserTriggerHandler. Musisz iść do jakiejś bzdurnej TriggerHandlerFactory, która wywołuje jakieś inne bzdurne klasy, które wywołują inne bzdurne klasy, które wywołują inne bzdurne klasy, i dopiero po przebiciu się przez 5 warstw bzdurnych, niepotrzebnych abstrakcji dochodzisz do czegoś, co w poprzednich projektach było zwyczajnie UserTriggerHandlerem. Każda z tych klas "rozwiązuje" problem, który na 99% nigdy nie powstanie, za to tworzy kilka nowych, już teraz, kiedy ja potrzebuję naprawić jakiegoś buga w tej istniejącej logice.
Szczerze mówiąc to ten kod z tymi całymi "enterprise patternami" jest równie nieczytelny, jak hinduso-kod pisany przez ludzi, którzy znali tylko i wyłącznie struktury "if" i "for", i zagnieżdżali je 25 razy, żeby osiągnąć pożądany rezultat, tyle że ten hinduso-kod można było śmiało przerabiać po kawałku na coś bardziej sensownego i było to mile widziane, a tutaj oczywiście jest system zaprojektowany przez doświadczonych architektów, znających wszystkie wzorce projektowe i w ogóle, i tego betonu już nikt nie ruszy, do końca świata.
Ja wiem, że "kto nigdy nie strzelił do komara z armaty, niech pierwszy rzuci kamieniem", ale dla niektórych programistów, a zwłaszcza architektów, to jest po prostu styl życia. Dlaczego oni muszą to robić?! I dlaczego ja potem muszę to nieczytelne spaghetti napisane zgodnie ze wszystkimi SOLIDami i innymi śmiesznymi skrótami z ewidentnym pominięciem tego najważniejszego (KISS) utrzymywać?!
Nienawidzę tej roboty.
Rant over.

cerrato
Tak z ciekawości - kod podany jako ilustracja to rzeczywisty kod z produkcji, napisany na szybko żeby pokazać o co chodzi, czy znaleziony gdzieś w necie?
CR
Napisany na szybko, żeby pokazać o co chodzi.
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:14 dni
2

Ostatnio czytałem artykuł o tym, że w większości wielkich firm, zbyt szybko wyciąga się uzdolnionych devów na wyższe stanowiska, przez co w pisaniu kodu jest ciągły niedosyt ludzi, którzy rozumieją co robią (pomijając w ogóle, że mało jest ludzi z odpowiednimi predyspozycjami i realnym wykształceniem). Natomiast ludzie, którzy nie rozumieją musza pisać na pałę, w jeden z dwóch sposobów, które wskazałeś. Z dwojga złego, to podejście „overengineered” trochę łatwiej zmodyfikować na zasadzie dodania jeszcze jednej warstwy lub przekierowania z jednego miejsca w drugie, trochę łatwiej usunąć obiekt i przemieścić go.


edytowany 2x, ostatnio: elwis
nowy_kret_2
  • Rejestracja:prawie 4 lata
  • Ostatnio:około 16 godzin
  • Postów:305
3

korporacje to czesto przechowalnie dla slabych programistow.

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
13

Jest dużo przyczyn. Raczej nie chodzi o złośliwość:

  • każdy kiedyś żałował, że nie zrobił gdzies dodatkowej warstwy abstrakcji, więc potem już wpiernicza w podobne miejsca, czy to ma sens czy nie (chyba sam najczęściej w tą pułapkę wpadam),
  • chęć ogarnięcia projektu w jeden spójny sposób, więc produkujemy ultra generyczny pattern, który pasuje na wszystkie funkcje w projekcie (mimo że w 90% kodu jest overkillem),
  • moda i kargo kult - widziałem, że kolega robił taki pattern więc też będę robił (nieważne, że to był inny projekt), ktoś na blogu pokazał fajny pattern... może się kiedyś przydać więc wrzucamy na zapas,
  • braki w języku programowowania łatamy warstwami - (specyficzne dla javy i podobnych języków), tu trudno coś nawet poradzić,
  • opór korpoarchitektów i korpomanagierów przed zmianami- nie można uprościć uprzednio wypracowanych patternów, bo poprzednie projekty tez były tak zasrane, ale się udały (w końcu z bólem weszły na produkcję) (to, że zwolniła się połowa programistów, a projekt przez 90% czasu był w fazie łatania błędów już umyka),
  • specyficzny sposób pokazywania kto ma większe cojones (przez narzucenie własnego patternu, lub pokazywanie innym, że są głupi bo nie ogarniają),
  • chyba na koniec najważniejsze: 95% korpoarchitektów wymyślających takie frameworki nie pisze w nich nic większego niż todo-list, nie widzi problemu

jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
Marcin Marcin
Jeszcze jest do tego strategiczne DDD - Dawaj Dawaj Diploj przy taktycznym DDD - Deadline Driven Development bo się naoglądają Sobótki i później w to wierzą
SH
SH
  • Rejestracja:ponad 3 lata
  • Ostatnio:ponad 3 lata
  • Postów:69
3

Skoro kasa jest proporcjonalna do ilości linii ...

Właśnie odnawiam kod w starszych projektach, i ogromne ilosci linii kasuję - chyba powinienem oddać kasę klientowi ?

CR
To ja jakiś rok temu usunąłem z 50% linii kodu z jednej appki, a wraz z tymi 50% linii kodu większość bugów. To może i za bugfixy powinniśmy oddawać, bo przecież usuwasz, a nie dodajesz?
ToTomki
Powinieneś płacić za to że usuwasz kod
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 2 godziny
  • Postów:2368
3

Trzeba uwzględnić, że takie korpo-warstwy mogą rozwiązywać problemy w chwili T0, ale w chwili T0+2 lata, problemy z T0 są nieistotne. Kod został.

Nie słyszeliście nigdy "zróbmy jakieś założenia"? Moim zdaniem stopień abstrakcji/przekombinowania wynika ze stanu wiedzy dostępnej na moment projektowania systemu. Po tym jak projekt jest wdrożony często przychodzi refleksja "można to było zrobić inaczej, prościej... gdyby tylko na początku było wiadomo, że X, Y, Z". No ale bywa tak, że brakuje wiedzy o tych X,Y,Z. Jeśli chcemy czekać (przeważnie chcemy, ale z różnych względów nie możemy), to idziemy w kierunku waterfalla.

Jak sobie radzić z brakiem wiedzy o szczegółach X? Przykryć X dodatkową abstrakcją? Jak odwrócić zależność od nieznanego Y? Interfejs i dostawca usługi?

Zobacz pozostałe 10 komentarzy
TS
Zgadzam się, tylko, że dużo częściej widziałem, że jednak feature Y na samym końcu nie jest potrzebny i niepotrzebnie się na nim skupiliśmy przez co udupiliśmy projekt bo klient najbardziej chciał X. Dużo częściej sprawdziła mi się opcja: 1. Zaimplementuj X 2. Zreleasuj projekt, zdobądź zaufanie klienta i hajs 3. Zrób Y i przepisz połowę systemu niż opcja z zaimplementowaniem X i Y jednocześnie, która kończyła się tym, że projekt stawał się tak skomplikowany i zbugowany, że upadał.
TS
Oczywiście, nigdy nie ma dwóch takich samym projektów. Być może w waszym przypadku opcja z Y od początku była słuszna. Mam za mało danych, żeby ocenić i nie rozmawiałem z waszymi managerami i klientem.
Wibowit
Zwykle robimy tyle ile trzeba, a nie na zapas. Wracając do tej ifologii (to był dość skrajny przykład, ale jednak był). Dotyczyło to nazewnictwa raportów, które wysyłamy do klientów. Do pewnego czasu wszyscy klienci zgadzali się na jeden format nazw, ale któregoś dnia pewien ważny (dużo płacący) klient zażyczył sobie wyjątkowego nazewnictwa. Wcześniej mieliśmy zahardkodowane nazewnictwo (założenie było takie, że skoro się nie zmienia to po co abstrakcje?). Po żądaniu od klienta mieliśmy dylemat: albo ifujemy w środku kodu dla kont klienta albo przerabiamy architekturę...
Wibowit
...tak, żeby nie trzeba było hardkodować w kodzie, tylko mieć nazewnictwo w bazie. To drugie wiązałoby się też z dodaniem GUI dla admina w starym (niby-mikro)serwisie, którego się powoli pozbywamy, bo jest napisany w przestarzałym frameworku. Po jakimś czasie z jednego klienta zrobiło się czterech, a więc hardkodowanie też się rozrosło i było pół-konfigurowalne, czyli dalej architekturalnie kiepsko, ale jeszcze bardziej skomplikowanie. W nowym rozwiązaniu, pisanym od zera, mamy dowolną konfigurowalność nazewnictwa i klienci, którzy mało płacą też będą mogli skorzystać.
Wibowit
Teoretycznie przeniesienie konfiguracji nazewnictwa do bazy i dorobienie GUI w starym serwisie miałoby sens mimo, że się tego serwisu powoli pozbywamy. Jednak wizja pozbywania się serwisu (czy chociażby wydzielenia do osobnego mikroserwisu konkretnej części odpowiedzialnej o wysyłanie raportów i gruntownego jej przerobienia) sprawiła, że ifologia dla jednego klienta nabrała atrakcyjności. Gdyby od razu było wiadomo, że takich klientów ma być co najmniej kilku to kładlibyśmy większy nacisk na zrobienie tego porządnie od razu i od razu nasz produkt byłby bardziej atrakcyjny.
WeiXiao
  • Rejestracja:około 9 lat
  • Ostatnio:około 16 godzin
  • Postów:5108
1

Czasem te skomplikowane patterny™ zwiększają poziom wejścia, ale gdy już zrozumiesz o co chodzi, jakie są konwencje itd. to faktycznie okazuje się że ma to ręce i nogi

Aczkolwiek konsultanci ewangelizujący też mają swoje za uszami :D

Kiedy gruboziarnisty kod jest lepszy?

Czy u was w pracy stosuje się Domain Driven Design?

edytowany 1x, ostatnio: WeiXiao
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
9

@Crazy_Rockman powodów może być wiele i czasami faktycznie jest tak że trafia się "przeinżynierowanie", ale uważałbym z takimi rantami, szczególnie jeśli w projekcie jesteś "nowy" i nie rozumiesz jeszcze do końca wymagań biznesu ani gdzie ten projekt jest umieszczony w ekosystemie innych projektów. Jeśli masz jakieś HandlerTriggerFactory to sugeruje że takich handlerów może być wiele z czego ty możesz sobie nie zdawać sprawy.

Każda z tych klas "rozwiązuje" problem, który na 99% nigdy nie powstanie,

Bardzo śmiałe założenie, ale znów bardzo ryzykowne. Moze taki problem już faktycznie "powstał" i w odpowiedzi na niego 3 lata temu dodano obsługę? :)

Ten twój przykład z DSLem jest bardzo fajny, sam robiłem jakiś czas temu coś podobnego, więc się do niego odniosę. Nie będę sie tutaj rozwodził nad szczegółami, ale w wielkim skrócie potrzebowaliśmy kawałka kodu, który z jednej strony można "ewaluować", a z drugiej strony wygenerować na jego podstawie w innym systemie SQLa. Ktoś patrząc tylko na ten system który potrzebuje natychmiastowej ewaluacji wyrażenia też mógłby rantować że po co robimy jakiś cyrk z DSLem, skoro można było bezpośrednio napisać kawałek kodu...

Generalnie zalecam patrzeć na cudzy kod wychodząc z założenia, że autor wiedział co robi, a nie z założenia ze autor to debil. Widziałem wiele razy (i sam też się na tym łapałem) akcje w stylu "przepiszmy ten kawałek kodu, bo przecież da się to zrobić 100 razy prościej", co po kilku dniach/tygodniach kończyło się zaoraniem brancha, bo okazywało się, że jednak nie da się prościej, zeby obsłużyc wszystkie przypadki użycia i spełnić wymagania biznesowe.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
RA
No tego żeby patrzeć na cudzy kod że autor wiedział co robi to bym się po Tobie moderatorze nie spodziewał.
CR
No właśnie trigger handlerów jest wiele i tego akurat zawsze jest wiele w działce, którą się zajmuję, ale w dotychczasowych projektach był abstrakcyjny TriggerHandler, z którego inne dziedziczyły - i sprawdzało się to bardzo dobrze. Ten projekt z kolei z jakiegoś powodu ma kilka warstw abstrakcji, żeby osiągnąć to samo. A żeby było śmieszniej, to rzeczy, które zawsze mieliśmy i działały, tu są w komentarzach jako TODO od 8 lat 😂
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:35 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
5

Zgadzam się że czasami jest przekombinowane, taki "overengineering". Robi się go "przekombinujmy" po to żeby "przekombinować".

Ale z kolei innym razem, to co niektórzy odbierają jako "przekombinowanie", lub "utrudnianie prostych zadań", jest po prostu generalny/ogólnym podejściem do problemu - zbyt ogólnym dla tych którzy nie znają dziedziny. Dla kogoś kto nie zna dziedziny, i chce zrobić "jedną prostą rzecz", możę wydawać się dziwne że musi skorzystać z innych elementów - dla niego to jest przekombinowane. Ale to czego nie wie ta osoba, to to że jego potrzeba jest tylko jedną z wielu, i dodatkowo jest jedną z rodziny problemów - i tym "przekombinowanym" sposobem można rozwiązać całą taką rodzię problemów.

Innymi słowy, czasem przekombinowanie jest przekombinowaniem, faktycznie. Ale czasem przekombinowane jest coś tylko przez ignorancję, i tak na prawdę jest świetnym rozwiązaniem.

Przykładowo, dla kogoś kto jeździł na automacie całe życie ręczna skrzynia biegów może być przekombinowana. Albo dla programisty node'a C może być przekombinowane. Dla programisty Vue.js - Angular może być przekombinowany. Ale czy są takie w istocie? Czy po prostu są bardziej ogólnymi rozwiązaniami?

PS: PHP jest przekombinowany koniec kropka.

edytowany 2x, ostatnio: Riddle
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:2 minuty
  • Postów:8406
5
  1. Bo programowanie na większą skalę jest trudne i ludzie próbują sobie radzić za pomocą tego co znają (mnóstwo wzorców projektowych "na zapas"), bo boją się spaghetti, które jest mało utrzymywalne. Problem w tym, że to, co potem powstaje, też jest mało utrzymywalne, ale cóż, nie dało się lepiej.

  2. Bo języki są mało ekspresywne. Często mam wrażenie, że to, czego potrzeba, to języki, które by ogarniały abstrakcje za nas, zamiast klepania ręcznie tych abstrakcji w postaci "wzorców projektowych" czy wydziwionych wewnętrznych frameworków. Dodajmy do tego, że wiele programistów nie zna dobrze języków, w których pisze, więc nawet nie wykorzystuje w pełni możliwości języka i kod jest bardziej zagmatwany niż mógłby być.

  3. Bo komercyjne i zespołowe pisanie ma dużą bezwładność. Pisząc sobie własny projekt hobbystycznie możesz popróbować różnych wzorców, a później stwierdzić, że dupa, to był błąd i przepisujesz wszystko od nowa w myśl zasady KISS. A w firmach się tak nie da, bo produkt już jest na produkcji, więc jak ktoś się pojechał za daleko z abstrakcjami, to już musi tak być. Chyba, że jednak podejmujemy decyzję o przepisaniu czegoś, ale to raczej zabawa na wiele dłużej, bo projekty są zwykle o wiele większe. Więc to przeinżynierowane legacy się ciągnie latami czasem.


edytowany 2x, ostatnio: LukeJL
nalik
Chyba ta bezwładność to strzał w sedno. Nikt z autorów się nie przyzna, że architektura ssie, a skoro działa to po co ruszać, jeszcze popsują. Wiec pudruje się trupa, a efekty stają się jeszcze bardziej opłakane.
WeiXiao
@nalik: Nikt z autorów się nie przyzna, że architektura ssie czy ja wiem?
nalik
@WeiXiao: oczywiście przemalowuję. Są ludzie skłonni do refleksji. Ale to raczej rzadkość.
nalik
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 2 lata
  • Postów:1039
2

Wyglada tak samo jak działa. Przecież klient musi wiedzieć, że płaci za produkt klasy enterprise ;)

A tak na serio, trudno zrobić czystą architekturę i ją utrzymać. Niektórzy pakują wzorce bez zastanowienia i spojrzenia na całość, tak to robili przez cała karierę zawodową i tak będą robić dalej.

edytowany 2x, ostatnio: nalik
S9
  • Rejestracja:ponad 4 lata
  • Ostatnio:około 2 lata
  • Lokalizacja:Warszawa
  • Postów:1092
8

Ja mam z kolei inną obserwację - czesty brak sensownych warstw abstrakcji i mieszanie kodu domenowego z infrastrukturą, np. encje JPA w logice biznesowej.


LukeJL
jedno drugiemu nie przeszkadza. Coś może być przeinżynierowane, a jednocześnie łamać zasady dobrego programowania.
Charles_Ray
Myśle, ze jakby nie było JPA tez byłby bajzel. Zobacz, ze często nie jest problemem to, że masz adnotacje w klasach (możesz ich w sumie nie mieć pisząc xmle ;p) tylko rozsmarowanie logiki biznesowej po wielu serwisach, przez co ficzery nie są dobrze zenkapsulowane, często zduplikowane i ciężko to dotykać. Nie zrzucajmy wszystkiego na JPA, to tylko narzędzie.
Miang
sensownych brak ale bezsensownych jest 6 tam gdzie wystarczyłyby ze 3, ale tak naprawðe jka @Charles_Ray pisze jest wszystko rozsmarowane w różnych miejscach więc nie ma ani jednej warstwy abstrakcji ;)
somekind
Coś może być przeinżynierowane, a jednocześnie łamać zasady dobrego programowania. - jeżeli coś jest przeinżynierowane, to z definicji łamie te zasady.
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 dni
  • Postów:3277
2

W momencie pisania tego kodu często nie są znane wymagania, więc (wydaje się, że) trzeba zrobić taki kod bardziej podatnym na wymagania, które pojawią się w przyszłości. Wymagania które były znane w momencie tworzenia kodu, przestały być wymaganiami w momencie w którym oglądasz ten kod. Możliwe, że w projekcie tydzień temu było szkolenie z wzorców projektowych/czystej architektury/pogadanka o SOLID, albo architekt przeczytał akurat jakąś książkę.

Miang
przyszedł studenciak który miał to na zajęciach i szefunio usłyszał i pomyślał że przecież skoro student to potrafi to każdy może (a student ledwo tróję dostał)
TA
  • Rejestracja:około 7 lat
  • Ostatnio:dzień
  • Postów:266
5

Przekombinowane rozwiązania, zazwyczaj mają bardzo pięknie brzmiące i stosunkowo proste uzasadnienia, dlaczego niby są takie świetne. Uniwersalność, możliwość konfiguracji i rozszerzania, użycie nowoczesnych narzędzi automatyzujących taką czy inną czynność... są dobrze wchodzącymi sloganami i nie wymagają jakiegoś dłuższego wstępu, aby pobieżnie tylko rozumiejący temat słuchacze nabrali entuzjazmu i pomyśleli - och, jakieś to mądre.

Jeśli ktoś z kolei rozumie jaki problem oprogramowanie ma rozwiązywać, ma doświadczenie w programowaniu i tej bądź pokrewnej dziedzinie, widzi że te entuzjastyczne wizje to puste slogany, i że to przekombinowane podejście stworzy mnóstwo problemów, a mało co rozwiąże, nie wytłumaczy tego w 15 minut jakiemuś członkowi zarządu, bo musiałby go wprowadzić w ogromną liczbę szczegółów, o których ten nie ma ochoty słuchać. Po wysłuchaniu obu stron, osoby decydujące ocenią rozwiązanie przekombinowane jako lepsze.

Charles_Ray
+1, często wymagania przychodzą z góry, że rozwiązanie musi być elastyczne, bo jak projekt się uda, to za 15 lat będziemy chcieli szybko dodać XYZ. Absolutny brak leanowego podejścia i empowermentu zespołu.
N0
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Gdańsk
  • Postów:647
1

Fajnie jakby w tym wątku zostały podane przykłady przeinzynierowania, bo jak na razie mamy tylko jeden przykład z factory, który jak napisali poprzednicy wcale nie musi być przekombinowany :)

Albo nie, osobny wątek lepiej założyć.

Przykłady przeinżynierowanego kodu

edytowany 2x, ostatnio: nobody01
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:2 minuty
  • Postów:8406
1

No ten przykład z pierwszego posta @Crazy_Rockman z zamianą int sum = 2 + 3; na wywołanie jakichś bobów budowniczych to w zasadzie niedoinżynierowanie, bo to wygląda tak, jakby ktoś chciał osadzić jakiegoś DSLa/minijęzyk skryptowy w aplikacji (stąd potrzeba dynamicznej zmiany operatorów czy wartości) i zamiast odrobić pracę domową czyli napisać tego prostego DSLa albo poszukać istniejącego (co byłoby w zasadzie bardziej odważnym rozwiązaniem niż tylko wrzucenie paru wzorców więcej), to idzie na pół gwizdka i robi "DSL dla ubogich" w postaci

Kopiuj
Integer a = IntegerBuilder
  .fromPrimitiveInt(2)
  .withSign('+')
  .build();

itp.

Tzn. przykład wygląda jak zmyślony, ale widziałem już podobne rzeczy naprawdę.


edytowany 2x, ostatnio: LukeJL
N0
to zmyslony przyklad, zobacz komentarze pod pierwszym postem :)
LukeJL
ale coś podobnego jest w Three.js (bibliotece do 3D), gdzie chcieli zrobić customowe materiały i wymyślili, że będą to "node materials" (czyli rozwiązanie, które się sprawdza np. w Blenderze, gdzie wizualnie się łączy strzałkami różne operatory i tworzy się graf reprezentujący materiał). Problem w tym, że bez wizualnego edytora budowanie tych grafów to właśnie taka katorga jak z tym IntegerBuilder. Plus brak dokumentacji i wychodzi na to, że łatwiej jest się nauczyć GLSL (języka shaderów w WebGL) i napisać w 1 linijce to, co w tych node materials będzie z 10 linijek.
Riddle
Administrator
  • Rejestracja:prawie 15 lat
  • Ostatnio:35 minut
  • Lokalizacja:Laska, z Polski
  • Postów:10056
2
LukeJL napisał(a):

No ten przykład z pierwszego posta @Crazy_Rockman z zamianą int sum = 2 + 3; na wywołanie jakichś bobów budowniczych to w zasadzie niedoinżynierowanie, bo to wygląda tak, jakby ktoś chciał osadzić jakiegoś DSLa/minijęzyk skryptowy w aplikacji (stąd potrzeba dynamicznej zmiany operatorów czy wartości) i zamiast odrobić pracę domową czyli napisać tego prostego DSLa albo poszukać istniejącego (co byłoby w zasadzie bardziej odważnym rozwiązaniem niż tylko wrzucenie paru wzorców więcej), to idzie na pół gwizdka i robi "DSL dla ubogich" w postaci

Kopiuj
Integer a = IntegerBuilder
  .fromPrimitiveInt(2)
  .withSign('+')
  .build();

itp.

Tzn. przykład wygląda jak zmyślony, ale widziałem już podobne rzeczy naprawdę.

Jak dla mnie, nie ma testu jednostkowego który mógłbyś napisać żeby rozróżnić Twój przykład z budowniczym od 2 + 3. Więc czemu miałbyś nie użyć "krótrszego" zapisu?

UR
  • Rejestracja:prawie 5 lat
  • Ostatnio:prawie 3 lata
  • Postów:360
1

O apkach enterprajs to chyba można biblię napisać.

Ja troszkę odbiję piłęczkę.
Uważam, że prawie największy wpływ na kiepski kod ma ... biznes.

Ciągle niesprecyzowane wymagania, zmiana w locie, myślenie że bycie agile i mając scrum robią wszystko OK.
Przez to powstaje kupa w kodzie, nieważne jak dobrze zaczniesz, lebiegi z biznesu ubiją każdy soft w firmie.

Milion pomysłów na początku, którym ucina się łeb i potem coś na szybko trzeba sklecić z istniejącego kodu.

Porywanie się z motyką na słońce, porzucanie pomysłów, wypalanie programistów z w/w powodów.
Zatrudnianie najtańszych też de facto decyzja biznesowa, nie wpływa pozytywnie na jakość kodu :D

No i architekci też mają swój wkład, generowanie modułów z T4 i inne badziewia.

KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:27 minut
  • Postów:2964
11

Większość tych rzeczy, które ludzie nazywają abstrakcjami, i zarazem to co opisał OP to tak naprawdę przekierowania/ pośredniość (indirection) a nie żadne abstrakcje.

Przekierowania i pośrednicy zwiększają stopień skomplikowania kodu. Każde miejsce gdzie możesz wpiąć inną implementację to przekierowanie. Im takich warstw więcej, tym kod czyta się trudniej, bo jest mało "mięska" a bardzo dużo "szkieletu".

Natomiast abstrakcja polega na tym, że zasadniczo upraszcza rozumienie kodu. Zamiast składać ręcznie bajty i pchać przez socket do bazy, od drodze jeszcze szyfrując, piszesz "addUser(user)" i sie robi. Dobra abstrakcja polega na tym że możesz opisać co robi takie "addUser" oszczędzając szczegółów jak to się tam naprawdę robi.

Abstrakcją jest baza danych, socket, plik, obiekt, iterator, drzewo, słownik itp. To są wszystko rzeczy dzięki którym pisze się prosciej bo pozwalają Ci trzymać w głowie znacznie mniej szczegółów (mniej niż wszystkie rzeczy faktycznie potrzebne do działania tych abstrakcji) a nadal jesteś w stanie ogarnąć system.

https://www.silasreinagel.com/blog/2018/10/30/indirection-is-not-abstraction/

edytowany 4x, ostatnio: Krolik
somekind
A w praktyce jak spytasz przeciętnego programistę czym jest abstrakcja, to dumny odpowie: "interfesjem!".
S9
@WeiXiao: pamiętaj - międzymordzie nie jest koniecznie abstrakcją! #PDK
N0
Jakoś nie mogę tego zrozumieć. Dlaczego TriggerHandlerFactory nie jest abstrakcja? Klient tej klasy nie musi wiedzieć, jak jest tworzony TriggerHandler, jakich zależności wymaga, nie musi nawet wiedzieć, jakiego jest typu jest ten TriggerHandler, którego akurat potrzebuje.
somekind
To czy jest, czy nie jest abstrakcją, zależy od tego, czym się faktycznie zajmuje. Z opisu autora wynika, że nie realizuje jednej rzeczy w całości, więc ciężko to uznać za dobrą abstrakcję.
Mjuzik
  • Rejestracja:ponad 8 lat
  • Ostatnio:minuta
  • Postów:712
1

Jeżeli sądzę, że coś można wykonać lepiej / prosciej to pytam autora kodu dlaczego zostało w ten sposób to zakodowane. Wtedy dosyć często autor opisuje sytuację, której nie wziąłem pod uwagę i daje sensowną odpowiedź. Dosyć często jest też druga odpowiedź. Gonił deadline i trzeba było robić na odpie*dol (npm przekopiować istniejący już kod z innego projektu) :D

W każdym razie, warto ze sobą rozmawiać i pytać.

edytowany 1x, ostatnio: Mjuzik
CR
  • Rejestracja:około 6 lat
  • Ostatnio:około godziny
  • Postów:112
0

Jak jestem w projekcie od początku, to robię review i pytam dlaczego tak, jeśli mam tego typu wątpliwości, ale w starym projekcie, do którego wpadłem miesiąc temu, a duża część autorów już dawno nie pracuje w tej firmie ta opcja nie istnieje.

Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
4

ta opcja nie istnieje

Niekoniecznie.

  1. Jest historia commitów i bardzo często zawiera odnośniki do jakiejś JIRY. Sprawdź skad się wziął ten "dziwny kod", kto i kiedy go dodał i co jest w commit msg
  2. Są testy. Zobacz co się stanie jak spróbujesz "uprościć" kawałek kodu - ile testów akceptacyjnych się wysypie bo usunąłeś krytyczną funkcje systemu o której istnieniu nie masz pojęcia

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Miang
jeszcze może być że jakaś ździra była zmieniona na inną i tej starej historii nie importowano ;)
CR
  • Rejestracja:około 6 lat
  • Ostatnio:około godziny
  • Postów:112
1

Może faktycznie się w ten sposób z tym pobawię. W sumie dziś trochę też pogadałem z tech leadem projektu, i o ile sam przyznaje, że sam niektórych rozwiązań nie uważa za idealne, to trzyma się tego, co zastał, żeby była spójność (jestem w stanie to uszanować), to sens paru rzeczy był w stanie mi wyjaśnić. Ogólnie założyłem temat jako taki "rant", ale trochę spostrzeżeń forumowiczów, oderwanie się od kodu na weekend i pogadanie na spokojnie z leadem i już jestem do tego projektu nastawiony nieco bardziej optymistycznie. Także dzięki wszystkim, którzy zabrali głos :)

.andy
  • Rejestracja:ponad 16 lat
  • Ostatnio:około 3 lata
  • Postów:1524
2

Ktoś tutaj fajnie to opisał wcześniej - ludzie trafiają do już istniejącego projektu, czasem long life. Taka osoba nie zna kontekstu powstawania takiego systemu, nie wie co się działo i jak powstawało.
Łatwo jest oceniać coś z boku po pewnym czasie. Pytanie czy mając tamte wymagania nie zrobilibyście inaczej?

Więcej dystansu w ocenie tego co zastajecie, bo często nie ma cie pojęcia w jakich warunkach kod powstawał i z czym się borykali ;)


Software is like sex: it's better when it's free.
- Linus Torvalds
KR
Moderator
  • Rejestracja:prawie 21 lat
  • Ostatnio:27 minut
  • Postów:2964
9

To wszystko prawda, ale przekombinowanie bierze się też stąd że zwykli programiści:

  • Nie umieją wcale pisać prostego kodu. I to nawet nie chodzi o brak YAGNI i cięcia funkcjonalności, tylko często ten sam kod potrafią napisać w sposób 3x bardziej skomplikowany niż mógłby być, zwykle przez niedostateczną znajomość języka, bibliotek lub zwyczajny brak zastanowienia się tylko klepanie pierwszego lepszego rozwiązania które przyszło im do głowy. Ostatnio np. gostek napisał kilkaset linii kodu parsujacego wyrażenia z OR i AND ręcznie ze stosem bo w projekcie w którym jest już ANTLR nie umiał zrobić gramatyki tak aby ANTLR parsował wszystko z dobrą precedencją operatorów. Ot, wolał napisać kilkaset linii niż doczytać jak zdefiniować kilka linii w ANTLR żeby wygenerować drzewko od razu z ANTLR. Innym razem inny senior zrobił drabinkę ifów na 6 przypadków, z czego dwa brzegowe niechcący pominął, a potem okazało się że wprowadzajac jedna zmiena pomocnicza można było to zredukować do bodajże jednego ifa, który był od razu poprawny.

  • Nie sprzątają. Jeżeli kod ma syf sprzed 10 lat, to znaczy że nikt nie sprzątał od lat. Nie można się wykręcać tym, że projekt ma 10 lat.

GZ
  • Rejestracja:około 4 lata
  • Ostatnio:około rok
  • Postów:35
0
Krolik napisał(a):
  • Nie sprzątają. Jeżeli kod ma syf sprzed 10 lat, to znaczy że nikt nie sprzątał od lat. Nie można się wykręcać tym, że projekt ma 10 lat.

Niestety tak jest a w wykręcaniu się niektórzy są bardzo kreatywni.

.andy
  • Rejestracja:ponad 16 lat
  • Ostatnio:około 3 lata
  • Postów:1524
0

@Krolik:

Nie umieją wcale pisać prostego kodu. I to nawet nie chodzi o brak YAGNI i cięcia funkcjonalności, tylko często ten sam kod potrafią napisać w sposób 3x bardziej skomplikowany niż mógłby być, zwykle przez niedostateczną znajomość języka, bibliotek lub zwyczajny brak zastanowienia się tylko klepanie pierwszego lepszego rozwiązania które przyszło im do głowy.

No ale przecież po to jest CR. Takie rzeczy powinny właśnie na nim wychodzić.

Ostatnio np. gostek napisał kilkaset linii kodu parsujacego wyrażenia z OR i AND ręcznie ze stosem bo w projekcie w którym jest już ANTLR nie umiał zrobić gramatyki tak aby ANTLR parsował wszystko z dobrą precedencją operatorów. Ot, wolał napisać kilkaset linii niż doczytać jak zdefiniować kilka linii w ANTLR żeby wygenerować drzewko od razu z ANTLR. Innym razem inny senior zrobił drabinkę ifów na 6 przypadków, z czego dwa brzegowe niechcący pominął, a potem okazało się że wprowadzajac jedna zmiena pomocnicza można było to zredukować do bodajże jednego ifa, który był od razu poprawny.

j.w. CR. PO to właśnie to jest aby unikać takich sytuacji.

Nie sprzątają. Jeżeli kod ma syf sprzed 10 lat, to znaczy że nikt nie sprzątał od lat. Nie można się wykręcać tym, że projekt ma 10 lat.

To też nie jest takie proste. Z jednej strony powinno się zostawić kod przynajmniej taki jaki zastaliśmy ale z drugiej strony jest ciśnięcie na terminy i często brakuje czasu...

Może trzeba być przypisane jakieś dodatkowe godziny na refactor? Np. na jakiś sprint wpada zadanie aby poprawić najbardziej śmierdzące kawałki kodu?


Software is like sex: it's better when it's free.
- Linus Torvalds
GZ
  • Rejestracja:około 4 lata
  • Ostatnio:około rok
  • Postów:35
1
.andy napisał(a):

j.w. CR. PO to właśnie to jest aby unikać takich sytuacji.

Nie sprzątają. Jeżeli kod ma syf sprzed 10 lat, to znaczy że nikt nie sprzątał od lat. Nie można się wykręcać tym, że projekt ma 10 lat.

To też nie jest takie proste. Z jednej strony powinno się zostawić kod przynajmniej taki jaki zastaliśmy ale z drugiej strony jest ciśnięcie na terminy i często brakuje czasu...

Nie ma czegoś takiego jak brak czasu. Istnieje natomiast brak organizacji, lenistwo, brak potrzeby sprzątania, umiejętność spychania projektów na innych pracowników, etc.

Shalom
Nie ma czegoś takiego jak brak czasu oczywiście że jest, kiedy klient płaci za ficzery i co tydzień czy dwa na demo masz je pokazać, a wcześniej uzgodnić w backlogu.
GZ
Tak, zgadza się. Jednak robiąc ten ficzer można poprawić drobną rzecz. Przy następnym kolejną. A PM / klient niech wie, że koszt projektu jest większy niż mu się wydaje.
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 7 godzin
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4707
4
.andy napisał(a):

Może trzeba być przypisane jakieś dodatkowe godziny na refactor? Np. na jakiś sprint wpada zadanie aby poprawić najbardziej śmierdzące kawałki kodu?

Sprinty naprawcze, refaktorowe, stabilizacyjne itp. Widziałem, przerabiałem, nie polecam. To jest takie zalegalizowanie syfu - robimy cały czas syf, a raz na jakiś czas poprawiamy - jeden ze sposobów jak wprowadzić projekt w bagno.
Prostsza metoda, która mi działała - przekonuje programistów, że zawsze przy szacowania mają podawać takie liczy, że uzwględniają:

  • zrobienie dobrze zadania, z testami i review,
  • z lekkim poprawieniem kodu dookoła - jak wiesz, że kod obok to syf to dajesz więcej

Jak prawie wszyscy w zespole mamy takie podejście, to się daje robić dobrze.
Brak czasu to raczej wymówka programistów. Wystarczy spytać projekt managera, PO czy kogoś tam czy chce aby zadanie było zrobione byle jak...


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
VA
  • Rejestracja:ponad 7 lat
  • Ostatnio:dzień
2

za y = a + b nikomu nie zapłacą 15k

za buildery z 10 warstwami abstrakcji już tak

nowy_kret_2
15k to teraz za dzien doobry daja
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)