Wątek przeniesiony 2019-07-29 15:33 z przez cerrato.

Nie rozumiem sensu programowania obiektowego

Odpowiedz Nowy wątek
2019-07-29 14:57
0

Zacznę o zastrzeżenia, że nie zamierzam, tu wszczynać wojny ideologicznej. Jak piszę, że czegoś nie rozumiem, oznacza to, że czegoś nie rozumiem, a nie że rzucam formalne wyzwanie wyznawcom odmiennego paradygmatu ;) Poza tym wiem też, że jestem po prostu hobbystką i zdaję sobie z tego sprawę, więc nie trzeba mi ani przypominać ani udowadniać ;)

Teraz w ramach wprowadzenia: mam ze 20 lat praktyki w rzeźbieniu czegoś tam w necie, ale zawsze robiłam to sobie na własny rachunek i bardzo "po swojemu", co tłumaczy, że:

Nie kumam sensu obiektówki :/ Rozumiem sensowność takiego podejścia w sytuacji, kiedy faktycznie mam manipulować na jakichś obiektach (np. elementach strony internetowej czy symulacji floty statków różnej klasy od czego podobno zaczęła się cała idea). Nie mam natomiast pojęcia do czego mi to w sytuacji typowych zastosowań, do których używam kodu:

  • policzyć coś i wyświetlić / zapisać,
  • wczytać dane z pliku, policzyć i wyświetlić / zapisać,
  • obsłużyć formularz / cms na stronie www.

W ciągu ostatnich kilkunastu lat robiłam do sprawy kilka podejść. Oglądałam jakieś przykłady prezentujące definiowanie klas zwierzątek albo samochodów, ich właściwości, metod, dziedziczenia i wszystko to rozumiem. Nie rozumiem natomiast po ch... mi to :/ jak niby i po co mam tego użyć w wymienionych powyżej zastosowaniach. Tymczasem autorzy po dojściu do tego etapu, wychodzą z założenia, że już wszystko wytłumaczyli. Więc kończy się zawsze tak, że po prostu wzruszam ramionami i piszę sobie dalej "po swojemu".

Rozumiem celowość tworzenia programu jako hierarchii pudełek przekazujących sobie parametry, ale (w moim mniemaniu) podobny efekt daje się uzyskać programowaniem proceduralnym, tworząc odpowiednią strukturę funkcji.

W dyskusjach odnośnie pojawia się dosyć często kwestia dziedziczenia i argument, że to ułatwia utrzymanie dużych projektów. Być może, nie będę się spierać, nie mając praktyki w dodawaniu kolejnych cegiełek do cudzych, rozległych systemów.


I teraz pytania:

Czy komuś chciałoby się poświęcić czas na ukazanie kilku elementarnych, praktycznych (nie zaś zwierzątkowo-abstrakcyjnyc) przykładów zastosowania programowania obiektowego z wytłumaczeniem dlaczego akurat tak?

Czy paradygmat obiektowy jest czymś uniwersalnym? Bo mam wrażenie, że to co może faktycznie się sprawdzać przy dużych projektach zastosowane dla zrobienia zwykłego "Witaj świecie" albo czegoś podobnego, to zwykłe przeinżynierowanie?

Ew. wszelkie inne uwagi odnośnie moich lamerskich wywodów.


edytowany 2x, ostatnio: Freja Draco, 2019-08-10 20:59
Pokaż pozostałe 9 komentarzy
Nie, tak nie miewam. Ogólnie jestem bardziej nastawiony na poprawianie tekstu niż "obrazków"; nie wiem w sumie, czemu. Nie lubię, gdy ktoś opuszcza jakieś zasady "bez powodu" (tzn. "równie dobrze" mógłby ich nie opuścić). - Silv 2019-07-29 15:13
I gdybyś podała mi wiarygodny (dla mnie) powód, dla którego napisałaś tytuł małą literą, byłoby to dla mnie równoznaczne z napisaniem go wielką, przynajmniej w sensie formalnym. - Silv 2019-07-29 15:15
Lubię też porządek, np. w pokoju. Gdy wszystko jest na swoim miejscu. To chyba powiązane z zasadami. - Silv 2019-07-29 15:27
że ty też miewasz czasem tak, że nie możesz się skupić, bo na ścianie jest kropka i kombinujesz, jak by można ją zetrzeć? Lol. Też coś takiego mam, chociaż właśnie jeśli chodzi o literówki. - LukeJL 2019-07-29 15:30
Może po prostu nie odpowiada taki styl programowania obiektowego jaki jest w C#, Java lub Kotlin. W Rust i Go jest trochę inaczej, zakochałem się w kodzeniu w Rust, najlepiej zaprojektowany język jaki widziałem. - sanny 2019-07-29 15:57

Pozostało 580 znaków

2019-08-10 08:52
1

Z perspektywy wannabe programmer OOP wydaje się dla mnie trudne (niezrozumiałe), bo dalej nie widzę eleganckiego rozwiązania następujących problemów:

1) Walidacja danych wejściowych. Przesyłasz do metody stringa, który może być częścią stanu obiektu? Upewnij się, że nie jest nullOrEmpty! Przesyłasz inta? Upewnij się, że nie jest ujemny! W efekcie dochodzi to tego, że połowa kodu encji to jakieś asercje preconditions, które są duplikacją walidacji z warstwy wyżej. Tu przykład, jeśli ktoś nie wierzy.

2) Komunikacja między obiektami. Można rzucić wyjątek, jeśli coś pójdzie nie tak (patrz przykład wyżej), ale potem odbiorca musi robić jakieś brzydkie try-catch. Można zwrócić Either/Result, ale wymaga to więcej pracy, a poza tym nie widziałem w żadnym publicznym repo, by ktoś tak robił. Można też zrobić jakieś dziwne rzeczy w stylu if (object.canIDoSth()) object.doSth(), ale to wygląda na wyciek logiki poza encję.

3) Modelowanie rzeczywistości. Powiedzmy, że mamy klasę Order. Zgodnie z OOP powinniśmy dać jej jakąś metodę changeStatus, jeśli chcemy zmienić stan zamówienia. Tylko czy w rzeczywistości zamówienie samo zmienia swój status? No nie, zmienia ten status obiekt Employee. Ponieważ pracownik jest odpowiedzialny też za wiele innych rzeczy, to jeśli chcemy zamodelować poprawnie rzeczywistość, to powinniśmy mieć jakąś boską klasę Employee z dostępem do źródła danych operującą na strukturach danych (np. Order). Brzmi znajomo?

Wszystkie powyższe przykłady dotyczą sytuacji, gdy używamy OOP do modelowania domeny.

edytowany 1x, ostatnio: nobody01, 2019-08-10 09:02
A czy na encji Coffee miałbyś metodę makeItself()? :) - Charles_Ray 2019-08-10 13:39

Pozostało 580 znaków

2019-08-10 16:21
4
nobody01 napisał(a):

3) Modelowanie rzeczywistości. Powiedzmy, że mamy klasę Order. Zgodnie z OOP powinniśmy dać jej jakąś metodę changeStatus, jeśli chcemy zmienić stan zamówienia. Tylko czy w rzeczywistości zamówienie samo zmienia swój status? No nie, zmienia ten status obiekt Employee. Ponieważ pracownik jest odpowiedzialny też za wiele innych rzeczy, to jeśli chcemy zamodelować poprawnie rzeczywistość, to powinniśmy mieć jakąś boską klasę Employee z dostępem do źródła danych operującą na strukturach danych (np. Order). Brzmi znajomo?

Miałem podobne problemy, gdy uczyłem się podstaw. Wg mnie myślenie o dosłownym modelowaniu rzeczywistości to pułapka. Kod obiektowy ma łączyć dane z metodami operujących na tych danych. To jest podstawa. Jeżeli kod odnosi się w pewien sposób do rzeczywistości, to jest łatwiejszy do zrozumienia. Ale dosłowne modelowanie, to syzyfowa praca nie warta czasu.
Równie dobrze mógłbyś myśleć, że jeżeli zamówienie ma metodę zmiany statusu, to nie jest to inteligentny obiekt, który sam sobie zmienia status, lecz reaguje na żądanie zmiany statusu, ukrywając mało istotne szczegóły implementacji. Kod związany z operowaniem na bebechach zamówienia nie jest w obiekcie pracownika, a właśnie zamówienia, bo jest to sensowny sposób połączenia kodu i danych, tj. enkapsulacji danych i wystawienia odpowiedniego interfejsu do operowania na tych danych. Być może nawet ten pracownik nie jest istotna abstrakcją i nie powinnien znajdować się w systemie.
W końcu chcesz stworzyć coś, co rozwiązuje jakiś konkretny problem, a nie dosłownie modelować świat.

edytowany 3x, ostatnio: nalik, 2019-08-10 23:05
Wydaje mi sie ze dosłowne modelowanie to cecha DDD, a nie samego OOP. - tdudzik 2019-08-10 16:34

Pozostało 580 znaków

2019-08-10 20:33
2

Kod obiektowy ma łączyć dane z metodami operujących na tych danych. To jest podstawa.

Dokładnie tak. Pisałem o tym wielokrotnie w tym wątku, ale zawsze można to powtórzyć jeszcze raz. Stworzenie klasy, która jest pojemnikiem na dane to nie jest OOP. To jest właśnie programowanie strukturalne.

Wydaje mi sie ze dosłowne modelowanie to cecha DDD, a nie samego OOP. - tdudzik dziś, 16:34

Czytam książkę Implementing DDD Vaughna Vernona i tam jest napisane coś wprost przeciwnego:
http://www.informit.com/artic[...]e.aspx?p=1944876&seqNum=4

  1. Agile, Iterative, Continuous Modeling
    The word “design” can evoke negative thoughts in the minds of business management. However, DDD is not a heavyweight, high ceremony design and development process. DDD is not about drawing diagrams. It is about carefully refining the mental model of domain experts into a useful model for the business. It is not about creating a real-world model, as in trying to mimic reality.

Na razie jestem na początku książki, więc nie mam wyrobionych intuicji dotyczących DDD. Naiwnych i błędnych intuicji typu "przepchałem funkcję do funkcji, więc programuję funkcyjnie", "stworzyłem klasę, więc programuję obiektowo", "wygenerowałem event, więc mam event sourcing" i tak dalej chcę oczywiście uniknąć.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
Być może masz rację, moja wiedza na temat DDD pochodzi z artykułów i konferencji, książka Evansa na razie czeka na półce, mogę więc się mylić. Ktoś tu podawał przykład z Employee jako obiektem, a skojarzyłem że jakieś źródło jako przykład serwisu domenowego podawalo Bookkeeper co jest akurat dość podobną sytuacją. Wg mojego zrozumienia jeżeli ekspert domenowy posługuje się pojęciem 'Pracownik', to obiekt o takiej nazwie powinien znaleźć się w kodzie. Głównie przez właśnie takie dylematy nie jestem zbyt chętny do zgłębiania DDD, bo można tak dywagować w nieskończoność :) - tdudzik 2019-08-10 22:50
Zgadzam się z tym brakiem precyzji i dywagowaniem. Za DDD się jednak wziąłem bo chcę być na bieżąco (inaczej mówiąc: bez znajomości DDD czuję się trochę jakbym miał braki w wiedzy). Z czasem pewnie zrozumiem "co autor miał na myśli", przynajmniej z grubsza. - Wibowit 2019-08-10 22:55

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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