W jednym z wielu anty-OOP na cat-v.org znalazłem fragment Joe Armstronga, który podniósł kilka zastrzeżeń przeciwko modelowi OOP, z których jeden był następujący:
Sprzeciw 4 - Obiekty mają stan prywatny
Państwo jest źródłem wszelkiego zła. W szczególności należy unikać funkcji wywołujących skutki uboczne.
Podczas gdy stan w językach programowania jest niepożądany, w rzeczywistości jest go mnóstwo. Jestem bardzo zainteresowany stanem mojego konta bankowego, a kiedy wpłacam lub wypłacam pieniądze z mojego banku, oczekuję, że stan mojego konta bankowego zostanie poprawnie zaktualizowany.
Biorąc pod uwagę fakt, że państwo istnieje w świecie rzeczywistym, jakie udogodnienia powinien zapewnić język programowania do radzenia sobie z państwem?
OOPL mówią „ukryj stan przed programistą”. Stany są ukryte i widoczne tylko poprzez funkcje dostępu. Konwencjonalne języki programowania (C, Pascal) mówią, że widoczność zmiennych stanu jest kontrolowana przez reguły zakresu języka. Czyste języki deklaratywne mówią, że nie ma państwa. Globalny stan systemu jest przenoszony na wszystkie funkcje i wynika ze wszystkich funkcji. Mechanizmy takie jak monady (dla FPL) i DCG (języki logiczne) służą do ukrywania stanu przed programistą, dzięki czemu mogą programować „tak jakby stan nie miał znaczenia”, ale w razie potrzeby mają pełny dostęp do stanu systemu.
Wybrana przez OOPL opcja „ukryj stan przed programistą” jest najgorszym możliwym wyborem. Zamiast ujawniać stan i próbować znaleźć sposoby na zminimalizowanie uciążliwości stanu, ukrywają go.
Co to dokładnie oznacza? Mam bardzo niski poziom doświadczenia lub procedur, głównie OOP, więc prawdopodobnie wyjaśnia to, jak bardzo się z tym nie znam. I z bardziej nowoczesnego punktu widzenia, skoro minęła już większość histerii zorientowanej obiektowo (przynajmniej o ile mi wiadomo), jak według was trafne / istotne jest to przejście?
Dzięki za pomoc.
źródło
Odpowiedzi:
W tym kontekście oznacza to, że OOP ukrywa stan programu, ukrywając go przed programatorem, ale nadal czyniąc go widocznym za pomocą (nieszczelnych) metod akcesorów. Argument jest taki, że zaciemnienie stanu utrudnia pracę, a przez to prowadzi do większej liczby błędów.
Uważam, że jest to istotne, ale źle ukierunkowane. Jest absolutnie problem, jeśli twoja klasa wycieka pojęcie swojego stanu do świata zewnętrznego. Jest absolutnie problem, jeśli twoja klasa próbuje ukryć stan, w którym powinien on być manipulowany przez świat zewnętrzny. To jednak nie jest wadą OOP jako całości, ale z indywidualnym projektem klasy. Nie powiedziałbym, że sam stan ukrywania jest problemem - monady cały czas robią to w programowaniu funkcjonalnym.
W najlepszym przypadku OOP działa jak najlepsza kombinacja programowania funkcjonalnego i proceduralnego - ludzie mogą korzystać z klasy „tak jakby stan nie miał znaczenia”, ponieważ państwo prywatne używane do ochrony niezmienników klasy jest ukryte, ale ma swobodę użyć dobrze zdefiniowanego publicznego stanu klasy, który wyodrębnia szczegóły.
Czy OOP utrudnia ludziom osiągnięcie tego najlepszego przypadku? Możliwie. „Szkoły Java” i cały Shape / Circle / Rectangle lub Car ma szkołę nauczania kół OO prawdopodobnie mają więcej do winy niż samo podejście. Współczesne OOP trochę zajmuje się programowaniem funkcjonalnym, zachęcając do niezmiennych obiektów i czystych funkcji, jednocześnie zniechęcając do dziedziczenia, aby ułatwić projektowanie klas, które działają dobrze.
źródło
Rozumowanie systemu będzie trudne, jeśli istnieją fragmenty o zmiennym stanie, które nie mają jednego wyraźnego „właściciela”. Nie oznacza to, że obiekty nigdy nie powinny mieć stanu zmiennego, ale raczej obiekty, które mają stan zmienny, nie powinny być używane w sposób, w którym własność może być niejasna, i odwrotnie, że obiekty, które będą musiały być swobodnie przekazywane bez śledzenia własności, powinny być niezmiennym.
W praktyce efektywne programowanie często wymaga, aby niektóre obiekty miały stan zmienny; taki stan powinien jednak ograniczać się do nieudostępnionych obiektów roboczych. Zastanów się nad interfejsami
IEnumerable
/IEnumerator
w .NET: jeśli kolekcja zostanie zaimplementowanaIEnumerable
, pozwoli na odczyt elementów pojedynczo. Rzeczywisty proces odczytu kolekcji będzie często wymagał śledzenia, które pozycje zostały odczytane (fragment stanu zmiennego), ale taki stan nie jest zawarty w implementacjiIEnumerable
. Zamiast tegoIEnumerable
udostępnia metodę o nazwie,GetEnumerator
która zwróci obiekt, który implementujeIEnumerator
i zawiera stan wystarczający do odczytania elementów z kolekcji. Fakt, że obiekt zawiera taki stan, nie będzie jednak stanowić problemu,jeśli implementacja obiektuIEnumerator
nie jest współdzielona .Najlepszym wzorcem w większości przypadków jest użycie mieszanki obiektów, które są swobodnie udostępniane, ale nigdy nie będą modyfikowane (przynajmniej nie po ich udostępnieniu) oraz obiektów, które mają wyraźnego właściciela i mogą być dowolnie modyfikowane przez tego właściciela , ale nigdy nie są nikomu udostępniane.
źródło
Ryzykując wykroczenie poza udzielenie odpowiedzi na pytanie, łatwo dostrzec wady w idei OOP, ale jestem skłonny sądzić, że siła pomysłu znajduje odzwierciedlenie w jego zdolności do nadużywania.
W końcu każdy ma swój ulubiony język, który opisuje w kategoriach „bardzo, bardzo potężny”, co oznacza, że naprawdę go lubi . Ale cudem uniwersalności obliczeniowej jest to, że bez względu na to, jak wspaniały jest język, jeśli jest naprawdę potężny, może symulować język asemblera. A jeśli tak, to ktoś to zobaczy. (Nie to, że z językiem asemblera jest coś nie tak).
Moje osobiste odczucia związane z modą OOP są takie, że stanowią one utrudnienie dla edukacji ludzi w zakresie inżynierii oprogramowania / informatyki. Są zahamowani na poziomie, na którym ich zdaniem chodzi o strukturę danych. Klasy, dziedziczenie, kontenery, iteratory, mapy skrótów, właściwości, ukrywanie stanu itp. - Wszystko o strukturze danych - tym bardziej wesołe.
Osobiście chciałbym zobaczyć kolejny poziom, w którym ludzie nauczyliby się rozwiązywać problemy, patrząc na nie pod względem językowym. Tam, gdzie rozumieją koncepcję języków specyficznych dla domeny, jak łatwo je tworzyć i pozwolić, aby ich tworzenie stanowiło integralną część rozwiązywania problemów. Nie jest błędem stwierdzenie, że struktura danych jest językiem. Ludzie powinni mieć taką umiejętność projektowania języka, aby nie tylko sobie z tym radzili.
Następnie, jako kolejny poziom, chciałbym, aby sztuczna inteligencja została wzmocniona. Chciałbym zobaczyć, jak programiści wychodzą poza bajty i wątki oraz tabele funkcji wirtualnych i CUDA i przechodzą do tego, jak zmusić maszyny do rozumowania, uczenia się i tworzenia. Wiem, że posunęło się to bardzo daleko w małych zakątkach pola, ale nigdzie nie jest wystarczająco szeroko.
źródło
powerful
właśnie tam. Kiedy inni mówiąpowerful
, mówią o tym, jak dobrze pozwala programistom na abstrakcję , co jest inną historią niż moc obliczeniowa .power
oznacza różne rzeczy. Proszę nie wprowadzać w błąd.Dostępność nie jest funkcją OOP, jest specyficzna dla implementacji takich jak Java i Microsoft dotNET. Główną cechą definiującą OOP jest polimorfizm.
W każdym razie, ukrywając stan obiektu, nie ma możliwości stworzenia sensownego API. Prezentacja jest istotnym elementem rzeczywistego OOP. Ci, którzy się nie zgadzają, prawdopodobnie mają irracjonalną wrogość do branży oprogramowania, co sprawia, że ich opinia jest nieistotna z mojego punktu widzenia.
Witryny takie jak ta, do której się odnosisz, słyną z wyjątkowo sztywnych przemyśleń i krytyki nowych technologii. Niektórzy po prostu tego nie rozumieją.
źródło