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

Nie rozumiem sensu programowania obiektowego

1

Błędnie podzielony na części składowe program proceduralny, łatwiej zmodyfikować niż błędnie podzielony na części program obiektowy.

Udowodnij.

3

Czym jest sens OOP, czyli jaki jest cel OOP? Proste ;)

Chodzi o zbudowanie rozwiązania problemu metodą Bottom-Up, gdzie dobrze zdefiniowane i nadające się do ponownego użycia rozwiązania (klasy) małych, dobrze zdefiniowanych problemów
składane są w większą całość. W podejściu strukturalnym, idzie to od drugiej strony, tzn. Top-Bottom, gdzie większy problem dzielimy na mniejsze, te na jeszcze mniejsze i rozwiązujemy te najmniejsze, które mogą, ale nie muszą nadawać się do ponownego wykorzystania.

Stąd też w OOP te wszystkie fabryki i interfejsy, bo jak bierzemy jakieś klocki (klasy) i chcemy zapewnić możliwość ich wymiany, to potrzebujemy wprowadzić "warstwę elastyczności", która to umożliwi. Im większą elastyczność chcemy, tym większa szansa, że skończymy z pierdylionem fabryk i interfejsów i ta elastyczność może złożonością przerosnąć rozwiązanie oryginalnego problemu (rozwiązania klasy "enterprajz").

3
Wibowit napisał(a):

Błędnie podzielony na części składowe program proceduralny, łatwiej zmodyfikować niż błędnie podzielony na części program obiektowy.

Udowodnij.

Nie wiem w jakiej formie dowody preferujesz, bo swoich własnych opinii dowodami nie podpierasz. Proszę, dla zilustrowania jak miałby taki dowód wyglądać, udowodnij - przykładowo - że przy pomocy OOP łatwiej utrzymywać duże projekty. Gdy zobaczę jak taki dowód może wyglądać, spróbuję na jego wzór zbudować własny - no chyba że Twój dowód będzie rzeczowy i bezbłędny i przekona mnie do zmiany zdania na temat OOP.

0

@Troll anty OOP:
pokaz kod ktory potwierdza Twoje zdanie. W taki sposob w jakis sposob udowodnisz

3

OOP tak naprawdę jest techniką, która ogranicza dowolność w pisaniu a daje niewiele. Właściwie jest tylko umową, że jeśli będziemy pisać w określony sposób, to wszystko będzie dobrze działać i w ogóle będzie tęczu. Tak samo jak z wcięciami: można nie robić wcięć wcale i też komuś to będzie pasować, poza tym jeden lubi spacje, drugi tabulacje.

2
yarel napisał(a):

Czym jest sens OOP, czyli jaki jest cel OOP? Proste ;)

Chodzi o zbudowanie rozwiązania problemu metodą Bottom-Up, gdzie dobrze zdefiniowane i nadające się do ponownego użycia rozwiązania (klasy) małych, dobrze zdefiniowanych problemów

Można, ale mało osób tak robi.

Projekty OOP właśnie bardzo czesto są pisane top-down, na zasadzie przeinżynierowania zaprojektowania całej apki za pomocą nawrzucania wzorców projektowych, klas, dziedziczenia, różnych innych syfów i dopiero potem się (niestety) myśli o konkretnych rzeczach, które aplikacja powinna robić pod kątem biznesowym.

Stąd też w OOP te wszystkie fabryki i interfejsy, bo jak bierzemy jakieś klocki (klasy) i chcemy zapewnić możliwość ich wymiany, to potrzebujemy wprowadzić "warstwę elastyczności",

Ale przecież właśnie te wszystkie wzorce projektowe sa często używane do nadania projektowi odgórnej struktury jeszcze przed napisaniem jakiegokolwiek kodu "biznesowego" - czyli mamy programowanie top-down.

Nie mówię, że jakaś postać programowania top-down i odgórnej struktury nie jest potrzebna, ale to co się wyrabia w wielu projektach OOP to jakaś masakra.

Oczywiście w OOP można programować bottom-up, i zgodziłbym się, że OOP to umożliwia w fajny sposób (enkapsulacja choćby czy podział na niezależne obiekty), tylko, że:

  1. to zależy od programistów czy będą pisali top-down czy bottom-up (gdzie żadna postać nie jest idealna - bo top-down zwykle kończy się na przeinżynierowaniu, a bottom-up może skończyć się na spaghetti kod, albo big ball of mud).
  2. to nie jest żadna przewaga OOP nad innymi paradygmatami (szczególnie biorąc pod uwagę programowanie funkcyjne, które jeszcze mocniej umożliwia takie pisanie, bo tam można wydzielać sobie poszczególne funkcje, które na dodatek nie mogą mieć skutków ubocznych, więc są jeszcze lepiej zenkapsulowane niż przeciętna klasa w OOP).
1
PerlMonk napisał(a):

OOP tak naprawdę jest techniką, która ogranicza dowolność w pisaniu a daje niewiele.

@PerlMonk: a w jaki konkretnie sposób OOP ogranicza wolność w pisaniu?

Właściwie jest tylko umową, że jeśli będziemy pisać w określony sposób, to wszystko będzie dobrze działać i w ogóle będzie tęczu.

A to z kolei, to kto stwierdził?

0
somekind napisał(a):
PerlMonk napisał(a):

OOP tak naprawdę jest techniką, która ogranicza dowolność w pisaniu a daje niewiele.

@PerlMonk: a w jaki konkretnie sposób OOP ogranicza wolność w pisaniu?

A no w taki, że jeśli chcesz nazwać kod obiektowym, to logika programu musi w jakiś sposób te obiekty reprezentować. Wyobraź sobie (czego ja oczekuję...), że w kodzie C++ nie użyjesz słów kluczowych struct, class i static do napisania kodu. Być może przyjdzie kolega i powie, że tam nie ma hermetyzacji i polimorfizmu.

Właściwie jest tylko umową, że jeśli będziemy pisać w określony sposób, to wszystko będzie dobrze działać i w ogóle będzie tęczu.

A to z kolei, to kto stwierdził?

Pewnie autor pojęcia OOP. Nikt nie mówi, że trzeba pisać określony kod w określonej strukturze, bo inaczej umrzemy.

2

Po pierwsze muszę przypomnieć najważniejsze, czyli definicję obiektu w OOPie. Obiekt to połączenie zachowania (metod/ funkcji) i stanu (pól). Stąd obiektem w sensie OOPa jest np taka struktura w C:

struct ToJestObiekt {
  int pole1;
  double pole2;
  int (*metoda1)(*ToJestObiekt);
  int (*metoda2)(*ToJestObiekt);
  int (*metoda3)(*ToJestObiekt);
}

Klasy (czy też np prototypy w JavaScripcie) są po to by zdeduplikować metody. Po co trzymać osobno wskaźniki do tej samej funkcji skoro można ten wskaźnik mieć raz w deklaracji klasy?

Dziedziczenie, enkapsulacja, itp dodatki są rozwinięciem OOPa, a nie jego fundamentem. Jeśli ktoś jest wkurzony na rozwinięcia OOPa to niech wskoczy np do Pythona - tam można spokojnie pisać obiektowo bez dziedziczenia i enkapsulacji, a nawet można usuwać albo dodawać metody do obiektów w locie (co jest oczywiście dalej OOPowe).

Troll anty OOP napisał(a):
Wibowit napisał(a):

Błędnie podzielony na części składowe program proceduralny, łatwiej zmodyfikować niż błędnie podzielony na części program obiektowy.

Udowodnij.

Nie wiem w jakiej formie dowody preferujesz, bo swoich własnych opinii dowodami nie podpierasz. Proszę, dla zilustrowania jak miałby taki dowód wyglądać, udowodnij - przykładowo - że przy pomocy OOP łatwiej utrzymywać duże projekty. Gdy zobaczę jak taki dowód może wyglądać, spróbuję na jego wzór zbudować własny - no chyba że Twój dowód będzie rzeczowy i bezbłędny i przekona mnie do zmiany zdania na temat OOP.

Przede wszystkim nie widzę potrzeby przekonywania cię do czegokolwiek. Co najwyżej warto by było przekonać cię, że OOP tak samo jak FP, kacze typowanie, statyczne typowanie, metaprogramowanie, itp itd to tylko narzędzia, które trzeba nauczyć się używać i wyrobić sobie intuicje co do tego kiedy które narzędzie jest przydatne.

Nie bardzo chce mi się szukać przykładów, bo temat jest o tym czym jest OOP a nie czy OOP jest dobry albo zły. Jednak natknąłem się na ciekawy przykład. Projekt jest duży i nazywa się Linux Kernel. Problem jest mały bo nazywa się lista wiązana. Oto jak koszmarnie wygląda implementacja listy wiązanej w C: https://kernelnewbies.org/FAQ/LinkedLists Przy tym czymś to LinkedList z Javy wygląda jak czyste złoto - można wyprodukować znacznie czytelniejszy kod do obsługi list, a brak potrzeby korzystania z makr kompilatora w Javie sprawia też, że komunikaty błędów kompilacji są zrozumiałe.

Osobną sprawą jest to, że alternatywą dla klas z OOPa mogą być np typeclassy z FP, ale te wcale nie muszą być prostsze. Hierarchie zależności między typeclassami też mogą być mocno przeinżynierowane. W ogólności każdy elastyczny sposób abstrakcji może być nadużyty bo można go nawarstwiać i komplikować w nieskończoność. Czy w takim razie powinniśmy schodzić na niski poziom? Przykład list wiązanych z Linuksa pokazuje, że to wcale nie upraszcza sprawy. Implementacja wygodnej w użyciu w OOPie rzeczy jest toporna w języku C.

1
Wibowit napisał(a):

Nie bardzo chce mi się szukać przykładów, bo temat jest o tym czym jest OOP a nie czy OOP jest dobry albo zły. Jednak natknąłem się na ciekawy przykład. Projekt jest duży i nazywa się Linux Kernel. Problem jest mały bo nazywa się lista wiązana. Oto jak koszmarnie wygląda implementacja listy wiązanej w C: https://kernelnewbies.org/FAQ/LinkedLists Przy tym czymś to LinkedList z Javy wygląda jak czyste złoto - można wyprodukować znacznie czytelniejszy kod do obsługi list, a brak potrzeby korzystania z makr kompilatora w Javie sprawia też, że komunikaty błędów kompilacji są zrozumiałe.

Taka implementacja listy z C posiada dodatkowe właściwości, których standardowe kontenery z C++ nie mają (z Javy zapewne też nie, ale wolę się wypowiedzieć o C++ bo jest mi bardziej znane): element może być na kilku listach jednocześnie, albo może być jednocześnie w tablicy i na liście. I wędrując po jednej liście, po dojściu do interesującego elementu, można zacząć od tego elementu i iść po drugiej. Nie wiem co prawda, czy ta właściwość jest w kernelu wykorzystywana, ale wydaje mi się to prawdopodobne.

Ja używam analogicznej implementacji listy w userspace i zdarza mi się, że mam elementy w tablicy a jednocześnie na liście. I na przykład dostaję się do elementu przez indeks w tablicy, robię jakąś modyfikację, po czym przesuwam go w inne miejsce na liście (np. liście-harmonogramie, kiedy najpóźniej trzeba wykonać jakąś operację na tym elemencie). W innym momencie korzystam wyłącznie z listy-harmonogramu zamiast tablicy.

Te operacje na makrach, w przypadku akurat listy, może ładne nie są, ale da się dość szybko przyzwyczaić i wcale nie tak znowu łatwo o popełnienie błędu, przed którym zabezpieczałby interfejs listy jaki jest w C++. Ja w każdym razie nie mam żadnych złych doświadczeń z taką implementacją listy.

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

Robot: CCBot