Prostota wynika z abstrakcji czy jej braku?

1

Oczywiście, że prostota wynika z abstrakcji, a nie jej braku

Tylko prostota czego? Czytania? Zrozumienia? Debugowania? Rozszerzania? Jak to napisał @slsy w komentarzu - dobra abstrakcja jest dobra. Tym nie mniej nawet jeśli odrzucimy fakt, że ludzie mocno przeginają i założymy że dorzucamy tylko tyle szumu ile wydaje nam się konieczne to i tak później osoba, która to będzie czytać/modyfikować ma do rozwiązania dwie zagadki - jaki problem kod rozwiązuje oraz jaki mentalny model autor kodu miał w głowie.

Zwolennicy OOP i pracy na wyższym poziomie abstrakcji wmawiają nam, że istnieje głównie ten drugi problem a ludzi nie mających ochoty rozwikływać zagadek pod tytułem "co autor miał na myśli" lubią wrzucać do worka "on nie rozumie architektury". Tylko, że abstrakcje ciekną i tak jak pisałem akapit wyżej, cześciej niż rzadziej programista ma przed sobą dwa problemy do rozwikłania - ten faktyczny oraz ten wymyślony przez kolegów z zespołu.

Jak żyć w takim razie? Nie mam pojęcia. Sam jednakoż uznałem, że OOP generuje za dużo szumu i zresetowałem moje podejście do architektury dziesięć lat wstecz, zanim zacząłem go używać, uczę się budować relacje między systemami na nowo. Okazało się, że programowanie przychodzi mi dużo łatwiej gdy jedyne czym się przejmuje to faktyczny problem jaki mam a nie co jakiś guru OOP pomyśli o moim kodzie. Nie wszystko związane z OOP jest złe, z tymże te dobre elementy przychodzą naturalnie bez konieczności pochłaniania ksiązek autorstwa programistycznych teoretyków.

Jak do tej pory mam tylko dwie twarde zasady

  1. Kod najpierw musi być używalny zanim stanie się reużywalny.
  2. Abstrakcje najczęściej są warte wprowadzania tylko gdy budujemy relacje między większymi systemami projektu, gdzie kilka luźno leżących funkcji załatwiających nam jakieś I/O to również abstrakcja.

I tak naprzykład chcąc mieć system działający na wielu pratformach konieczne będzie wyabstrahować sobie warstwę platformową, mając serwer http nie powinniśmy na codzień przejmować się niskopoziomową rejestracją i rutowaniem URLi. Tym samym czy konieczne byłoby używanie jakiś grubych abstrakcji, żeby przykładowo pobrać informację EXIF z jpg? Wystarczy na to jedna funkcja parsująca i jeden prosty kontener na dane, ale widziałem też, że ludzie budują wokół tego całe diagramy klas zupełnie niepotrzebnie i w tym przypadku dodatkowo abstrakcja mocno utrudnia.

2

Abstrakcja to pojęcie znacznie szersze, i można jej używać nie tylko bez OOP, ale i bez programowania w ogóle.
A jeśli ktoś robi OOP z cieknącymi abstrakcjami, i ktoś potem nie może się w tym odnaleźć, to jest to dowód na niedziałanie braku abstrakcji właśnie.

Abstrahowanie oznacza dzielenie na problemy rozwiązywalne na jednym poziomie, nie tworzenie skomplikowanych rozwiązań. To drugie to overengineering.

1

A jeśli ktoś robi OOP z cieknącymi abstrakcjami, i ktoś potem nie może się w tym odnaleźć, to jest to dowód na niedziałanie braku abstrakcji właśnie.

No niekoniecznie. Jeśli abstrakcja Ci cieknie i musisz rozwiązywać problemy na dwóch poziomach to bez jednego z tych poziomów powinno być prościej. Warstwy rozwiązującej problem nie usuniesz, za to możesz usunać wadliwą abstrakcję.

Anyway, co do reszty mam wrażenie, że się ze sobą zgadzamy, tylko używamy do tego innych słów lub patrzymy na sprawę pod innymi kątami.

4

Dostrzegam drobny problem.

Człowiek z małym doświadczeniem w tworzeniu abstrakcji (np. ja) będzie tworzył wadliwe abstrakcje, bardziej utrudniające niż ułatwiające, bo tworzenie poprawnych abstrakcji to sztuka. Kod pisany najprościej, jak to możliwe (tu najprościej w sensie: w sposób najbardziej naiwny) będzie lepszy, niż kod zawierający wadliwe abstrakcje.

Z drugiej strony tylko tworząc abstrakcje można się nauczyć tworzenia poprawnych abstrakcji? Więc faza produkowania zoverengineerowanych potworków jest konieczna?

A może nie? może raczej konieczna jest faza pisania naiwnego kodu pozbawionego abstrakcji, potem nacięcia się na skutkach braku abstrakcji i na tej podstawie zrozumienia, które i jakie abstrakcje są naprawdę potrzebne? Potrzebne abstrakcje = te, które bronią mnie przed problemami, o które już się odbiłem. Skoro już się odbiłem o jakiś problem, to pewnie będę lepiej wiedział, jak mu zapobiec na przyszłość. Natomiast będzie mniej prawdopodobne, że wpadnę w pułapkę rozwiązywania nieistniejących problemów kosztem tworzenia innych problemów

W jedną czy w drugą stronę... jak się nie wywrócisz, to się nie nauczysz.

3

no ale chyba prawie wszystko tak działa?

0

Chyba wam się forum pomyliło, takie rozważania to forum dla filozofów.

7

Abstrakcja to z definicji upraszczanie (== odcinanie szczegółów).

Jeśli więc abstrakcja nie upraszcza to albo coś nie tak z konkretną abstrakcją - złe użycie, albo coś nie tak z pojęciem prostoty u analizującego (to drugie dość częste).

3
jarekr000000 napisał(a):

Abstrakcja to z definicji upraszczanie (== odcinanie szczegółów).

Jeśli więc abstrakcja nie upraszcza to albo coś nie tak z konkretną abstrakcją - złe użycie, albo coś nie tak z pojęciem prostoty u analizującego (to drugie dość częste).

I to jest chyba istota. Ludzie w większości kojarzą "abstrakcję" z czymś bardziej skomplikowanym bo w przypadku programowania sam proces implementacji abstrakcji zwykle wymaga większego doświadczenia, wysiłku umysłowego niż implementacja czegoś "wprost / na pałę". Dlatego ludzie myślą, że abstrakcja to coś trudniejszego a nie uproszczonego.

Weźmy taki banalny CSS / HTML, w którym możemy temat ogarnąć na 2 sposoby:

  1. przypisywać kolory i rozmiary fontów wprost do konkretnych elementów na stronie ( do div, span, p itp... )
  2. stworzyć sobie warstwę abstrakcji w postaci kilku klas lub nawet z wykorzystaniem zmiennych CSS.

Młodemu i początkującemu programiście zapewne łatwiej będzie przypisać kolor i rozmiar fontu do konkretnego DIV'a niż stworzyć z głową zmienne i klasy, które będą wykorzystywane w różnych miejscach kodu. Zatem sposób pierwszy jest zapewne "łatwiejszy" i pozornie szybszy.
Drugą metodą także możemy uzyskać taki sam efekt, zatem wizualnie w obu przypadkach oczywiście osiągniemy to samo ale nie korzystając z warstwy abstrakcji jakie dają nam klasy i zmienne CSS stracimy potencjalne możliwości łatwiejszej modyfikacji całości.

Jeśli jednak ktoś powie, a teraz zrób przełącznik na tryby "dark mode" / "day mode" ( ciemny / jasny ) to nagle okaże się, że użycie abstrakcji w postaci klas i zmiennych upraszcza to zadanie właściwie do minimum bo zmieniamy tylko wartości zmiennych. Natomiast w przypadku pierwszym musimy klepać wszystko drugi raz albo szukać jakiś kombinowanych rozwiązań.

Zatem o ile to ma potencjalny i uzasadniony sens to należy z abstrakcji korzystać.
Jest też druga strona medalu bo z abstrakcjami można grubo przegiąć... Co też nie jest dobre.

4
katakrowa napisał(a):

Jest też druga strona medalu bo z abstrakcjami można grubo przegiąć... Co też nie jest dobre.

Przeginki biorą się często z tego, że ludzie nie rozumieją sensu abstrakcji, z których korzystają, a tylko naśladują.
Np. ktoś poczyta o DDD, CQRS itp. i zaczyna wrzucać całą maszynerię, o której wyczytał w książce, bez ładu i składu. Pisze, żeby pisać. Próbuje odtworzyć porządek i nazewnictwo klas z książki nie rozumiejąc, jakie problemy te klasy mają w ogóle rozwiązywać (czyli typowy cargo cult).

Drugi powód, który widzę, to jak ktoś się uczy na produkcji. Tzn. moim zdaniem "przeinżynierowanie" jest normalnym etapem nauki. Poznasz jakiś wzorzec, to chcesz go stosować wszędzie. Albo wpadasz na jakiś "genialny" pomysł (np. zrobienie skomplikowanego wrappera na istniejący framework), to czujesz, że musisz go koniecznie wypróbować. I to jest spoko jak robisz to w swoich projektach do szuflady albo nawet w ramach pracy, ale jako PoC/eksperyment. Tylko, że ludzie wolą uczyć się na produkcji. Eksperymenty, które w ogóle do mastera nie powinny trafić, są merdżowane, a później utrzymywane przez długi czas (najpierw traktowane jako "genialna nowa implementacja", a później już tylko jako legacy, bo "to stary kod, ale wtedy myśleliśmy, że to dobre podejście. Myliliśmy się")

1 użytkowników online, w tym zalogowanych: 0, gości: 1