Co oznacza „OOP ukrywa państwo”? [Zamknięte]

11

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.

Jake
źródło
3
zalecana lektura: Porozmawiaj o tym {blog}
gnat
1
Jeśli mnie zapytasz, artykuł, do którego się odsyłasz, zawiera kilka dość kiepskich argumentów (nie wspominając o jakości pisania). Nie wkładałbym zbyt wiele w to, co ma do powiedzenia.
Benjamin Hodgson
1
Bah. Coraz bardziej myślę, że cała ta „niezmienna” rzecz jest dobrym pomysłem, który zaczyna śmierdzieć religią.
Rob
3
Joe Armstrong publicznie przyznał, że jego zarzuty wobec OO były oparte na poważnych nieporozumieniach dotyczących tego, czym jest OO. Teraz zdał sobie sprawę, że Erlang jest językiem głęboko zorientowanym obiektowo (w rzeczywistości może być językiem najbardziej zorientowanym obiektowo w powszechnym użyciu).
Jörg W Mittag
9
Aby rozwinąć tę kwestię: pierwsze przechwytywanie archiwum.org z oświadczeniem Joe Armstronga pochodzi z kwietnia 2001 r. Joe napisał swoją pracę dyplomową w 2003 r. Podczas pisania swojej pracy wiele się nauczył o OO i zdał sobie sprawę, że padł ofiarą powszechne błędne przekonanie, że OO było w jakiś sposób związane ze stanem zmiennym (nie jest, stan zmienny jest całkowicie ortogonalny). Od tego czasu przyznał, że jego krytyka OO była błędna i, jak na ironię, Erlang jest w rzeczywistości językiem zorientowanym obiektowo (ma wiadomości, ma obiekty, które nazywa procesami, ma hermetyzację).
Jörg W Mittag

Odpowiedzi:

32

Co to dokładnie oznacza?

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.

jak myślicie, jak trafny / istotny jest ten fragment?

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.

Telastyn
źródło
3
Zgadzam się całym sercem na temat całej „szkoły java”, wcale tego nie lubię heh. Dziękuję bardzo, zagłosowałbym, gdybym mógł.
Jake,
2
Mówiąc dokładniej: monady w ogóle nie ukrywają stanu, niektóre monady tak (np. IO). Zobacz między innymi stackoverflow.com/questions/2488646/…
thSoft
2
+1. Jest to o wiele bardziej zrównoważona i szczegółowa analiza niż artykuł, do którego połączył
poszukiwacz
2
Joe Armstrong publicznie przyznał, że jego zarzuty wobec OO były oparte na poważnych nieporozumieniach dotyczących tego, czym jest OO. Teraz zdał sobie sprawę, że Erlang jest językiem głęboko zorientowanym obiektowo (w rzeczywistości może być językiem najbardziej zorientowanym obiektowo w powszechnym użyciu).
Jörg W Mittag
2
Jorg - czy możesz zamieścić link do kontynuacji Joe? Byłbym bardzo zainteresowany, aby to przeczytać. I @radarbob, zaraz!
user949300
2

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/ IEnumeratorw .NET: jeśli kolekcja zostanie zaimplementowana IEnumerable, 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 implementacji IEnumerable. Zamiast tego IEnumerableudostępnia metodę o nazwie, GetEnumeratorktóra zwróci obiekt, który implementuje IEnumeratori 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 obiektu IEnumeratornie 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.

supercat
źródło
Doskonałe rozróżnienie między tym, co powinno być niezmienne a tym, co może mieć stan zmienny. Czytając to, zdałem sobie sprawę, że moje nowsze wykresy obiektowe (bardziej niezmienne niż kiedyś) w zasadzie są zgodne z tymi wytycznymi, ale nie są tak jasno określone, jak ty. Jest to dobre, umiarkowane antidotum na „świszczący stan, w którym zawsze jest zło”, jak to czasem słyszysz.
Mike wspiera Monikę
@Mike: Myślę, że prawdziwym problemem jest to, że wszystkie odwołania do obiektów w Javie i .NET są w pełni rozwiązane; każdy kod, który pozyskuje lub otrzymuje odniesienie do obiektu, może udostępniać go dowolnemu innemu kodowi, bez ograniczeń. Żadna z ram nie ma pojęcia pola odniesienia, którego nie można udostępnić; struktury i byrefy w .NET są bliskie, ale są raczej ograniczone pod względem tego, co mogą zrobić lub co mogą uniemożliwić wykonanie kodu zewnętrznego. W każdym razie
podałbym
... obecny stan obiektu w świecie rzeczywistym i stan, w którym obiekt ten był o 12:57. Jeśli rzeczywisty stan obiektu ulegnie zmianie, obiekt nie będzie już mógł reprezentować obu. Czasami konieczne będzie, aby obiekt nadal reprezentował stan 12:57, a czasami stan obecny. Związek między stanem o godzinie 12:57 a stanem obecnym nie może jednak pozostać, jeśli stan obecny się zmieni.
supercat
0

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.

Mike Dunlavey
źródło
1
„Jeśli jest naprawdę potężny, może symulować język asemblera” - zamieniasz definicję powerfulwł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 .
Phil
@Phil: streszczenie to kolejne z tych słów :)
Mike Dunlavey
Nie Mówiłeś o słowach. Mówiłem o pomysłach. Twoje 2. i 3. użycie tego słowa poweroznacza różne rzeczy. Proszę nie wprowadzać w błąd.
Phil
Btw, jeśli jesteś zainteresowany, sprawdź Rakieta , która jest nieco zbliżona do podejścia, o którym mówisz w czwartym akapicie (umożliwiając programistom dostosowanie języka do poziomu problemu, zamiast sprowadzania problemu do poziomu ustalony zestaw konstrukcji języka). Wykracza to daleko poza klasyczny Lisp / Scheme, na wypadek, gdyby ktoś miał takie wrażenie, kiedy na niego spojrzał.
Phil
0

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ą.

Leopold Asperger
źródło
Powinien istnieć obiekt chroniący niezmienniki modelowanej koncepcji. Prezentacja jest całkowicie odrębną kwestią i nie może być skutecznie i utrzymywana przez ten sam obiekt, ponieważ obiekt nie może zrozumieć wszystkich różnych sposobów prezentacji w czasie i przestrzeni. Prezentacja musi być obsługiwana przez inny mechanizm, taki jak przesyłanie strumieniowe zdarzeń i zmaterializowane widoki, jeśli Twoim celem są wszechstronne, łatwe do utrzymania obiekty. Jedyny moment, w którym obiekt powinien się zmienić, to zmiana jego koncepcji lub zmiana niezmienników.
Andrew Larsson,