Jedną z ważnych koncepcji programowania obiektowego jest enkapsulacja. Jednak ostatnio świat oprogramowania wydaje się przechylać na korzyść innych paradygmatów, takich jak programowanie funkcjonalne.
To sprawia, że myślę, a co z enkapsulacją i innymi zasadami OOP? Czy oni się mylą?
Czy to znaczy, że OOP jest źle stosowany? Na przykład Alan Kay znany jest z powiedzenia w Keynote OOPSLA'97: „Wynalazłem pojęcie obiektowe i mogę powiedzieć, że nie miałem na myśli C ++”.
Joe Armstrong - „Obiekty łączą funkcje i struktury danych w niepodzielne jednostki. Myślę, że to podstawowy błąd, ponieważ funkcje i struktury danych należą do zupełnie innych światów”.
Odpowiedzi:
Myślę, że pułapką, w którą wpadłeś, jest myślenie, że istnieje sztywna definicja każdego paradygmatu programistycznego (ustrukturyzowany, obiektowy, funkcjonalny i in.)
Jeśli zapytasz dwóch różnych programistów, co oznacza OOP, otrzymasz dwie różne odpowiedzi. Tak, jako zawód zgadzamy się, że istnieje kilka typowych tematów, takich jak enkapsulacja, ukrywanie danych itp., Objętych dowolną klasą inżynierii oprogramowania OOP na studiach.
Jednak w prawdziwym świecie rzeczy nie są tak wytrawne i suche, dlatego dwóch programistów udzieli dwóch różnych odpowiedzi. Być może są ekspertami w różnych językach, którzy inaczej wyrażają koncepcje OOP. Paradygmaty językowe często się pokrywają. Najnowszy trend z 2013 roku obejmuje programowanie funkcjonalne w językach obiektowych poprzez zamykanie lub lambdas. Czy Java 8 jest obiektowy lub funkcjonalny? Nazwałbym to obiektowym z odrobiną funkcjonalności. Ktoś inny mógłby to inaczej opisać.
Nie, problemem jest to, że różne języki różnie wyrażają koncepcje programowania. Być może jeden język pomija koncepcję OOP, a inny język ją zawiera, ale pomija inną koncepcję OOP. Języki są zwykle zaprojektowane w celu: ułatwienie określonego rodzaju zadania kosztem utrudnienia innych zadań. To nie jest ani dobre, ani złe, to po prostu kompromis w świecie rzeczywistym, którego nie można uniknąć.
Prawdziwy świat to nie klasa. Musimy albo omówić paradygmaty programowania koncepcyjnego na poziomie abstrakcyjnym, albo dyskutować o prawdziwych językach programowania, które zmuszone są do kompromisów, aby były przydatne. Tak długo, jak język programowania jest w większości definiowany przez abstrakcyjną definicję OOP, możemy uwzględnić go w tym segmencie.
źródło
To jest dyskusyjne. Po pierwsze, nie widzę żadnych innych paradygmatów poza OOP i programowaniem funkcjonalnym, które są szeroko omawiane, więc myślę, że możemy zapomnieć wyrażenie „inne podobne paradygmaty” , porozmawiajmy o FP, nic więcej.
Powody, dla których programowanie funkcjonalne stało się tak popularne w ostatnich latach, zostały omówione w innych pytaniach tutaj dogłębnie, nie zamierzam tego powtarzać (patrz tutaj lub tutaj , na przykład). Ale moim zdaniem nie dzieje się tak dlatego, że „OOP był wielkim błędem” lub „Funkcjonalne vs. OOP wzajemnie się wykluczają”, to raczej ludzie rozszerzający swój zestaw narzędzi i starający się uzyskać to, co najlepsze z obu światów. Ok, na pewno są eksperci, którzy są hardlinerami faworyzującymi się nawzajem, ale tych facetów znajdziesz po obu stronach.
Kapsułkowanie ma wiele różnych smaków. Funkcjonalne języki programowania i konstrukcje językowe zapewniają pewne formy enkapsulacji, inne obiektowe. Jeśli szukasz przykładów enkapsulacji za pomocą środków funkcjonalnych, zacznij od zamknięć .
Jeśli chodzi o „inne zasady”: nie, nie są one błędne, ale w niektórych scenariuszach, takich jak równoległe przetwarzanie na dużą skalę, podejścia funkcjonalne prawdopodobnie skalują się lepiej. W przypadku innych scenariuszy, takich jak tworzenie dobrze zaprojektowanych ram interfejsu użytkownika, podejścia OOP prawdopodobnie skalują się prawdopodobnie lepiej (YMMV, nie mam tylko lepszego przykładu pod ręką). Co więcej, jestem pewien, że w większości rzeczywistych scenariuszy zależy to od wiedzy i doświadczenia zespołu z jego ulubionym paradygmatem programistycznym, jak dobrze dany system będzie skalowany.
Z pewnością wiele osób stosuje źle OOP, ale jestem pewien, że to samo dotyczy FP. Byłbym zdziwiony, gdyby John Mc Carthy (projektant Lisp) miał na myśli coś w rodzaju Javascript, gdy myślał o programowaniu funkcjonalnym (litość dla mnie, nie rozpalaj mnie zbytnio dla tego porównania ;-)
Myślę, że wynalazca Erlanga ma kilka dobrych argumentów, ale ma także swój własny punkt widzenia, więc pozwól mu wyrazić swoją opinię i zbuduj własne. Jest wielu innych ekspertów, którzy mają inne zdanie na ten temat.
źródło
Oczywiście:
Wiem, co powiesz: „Ale to nie obejmuje również zachowania!” W tej kwestii jestem z Joe Armstrongiem: możesz pisać całe programy lub systemy operacyjne, nie wymagając obiektów najwyższej klasy. Linux to potwierdza.
Programiści JavaScript rutynowo hermetyzują stan i zachowanie w funkcjach i zamknięciach, a nie w klasach.
źródło
Głównym problemem jest to, że enkapsulacja nie jest sztywno zdefiniowaną koncepcją ani dlaczego jest przydatna. Przeprowadzenie niektórych badań pokazuje, że sposób, w jaki ludzie postrzegają enkapsulację, jest wysoce opiniotwórczy i że wiele osób myli ją z Abstrakcją.
Pierwsza definicja masz zamiar znaleźć się
Jeśli to twoja definicja, to większość języków ma możliwość grupowania danych i funkcji działających na tych danych w klasy, moduły, biblioteki, przestrzenie nazw itp.
Twierdziłbym jednak, że nie jest to głównym celem enkapsulacji, ponieważ definicja ta trwa:
Wikipedia zgadza się również, że:
Ale teraz musimy zapytać, co należy rozumieć przez „ingerencję i niewłaściwe użycie” i dlaczego należy ograniczyć bezpośredni dostęp do danych. Uważam, że istnieją dwa powody.
Po pierwsze, ograniczający zakres, w którym dane mogą być mutowane, leży w najlepszym interesie dewelopera. Zbyt często trzeba mieć logikę przed / po ustawieniu wartości. A posiadanie ograniczonej liczby miejsc, w których można ustawić wartość, jest niezwykle cenne. W językach OOP można to zrobić za pomocą klas. W „zmiennych” językach funkcjonalnych zamknięcia służą temu samemu celowi. A ponieważ wiemy, że klasy = zamknięcie , jest nawet dyskusyjne, że zmienne języki funkcjonalne są innym „paradygmatem” niż OOP.
Ale co z niezmiennymi językami? Nie ma problemu z mutowaniem zmiennych. Tu pojawia się drugi problem: powiązanie funkcji i danych pozwala utrzymać te dane w stanie, który jest poprawny. Wyobraź sobie, że masz niezmienną strukturę
Email
. Ta struktura ma jednostring
pole. Mamy wymagania, że jeśli masz wartość typu,Email
to pole zawiera prawidłowy adres. W enkapsulacji OOP można to łatwo zrobić, deklarując to poleprivate
, podając tylkoGet
metodę i mającconstructor method
udaje się to tylko wtedy, gdy przekazany ciąg znaków jest poprawnym adresem. Podobnie jest z zamknięciami. Teraz, dla niezmiennego języka, należałoby powiedzieć, że strukturę można zainicjować tylko za pomocą określonej funkcji i taka funkcja może zawieść. I nie znam żadnego języka, który spełniałby te kryteria (może ktoś w komentarzach może mnie oświecić).Ostatni problem dotyczy enkapsulacji języka „wspierającej”. Z jednej strony istnieją języki, które umożliwiają wymuszanie enkapsulacji, więc kod nie będzie się kompilował, jeśli enkapsulacja zostanie zerwana. Z drugiej strony język może zapewniać sposób enkapsulacji, ale nie wymusza go, pozostawiając programistom wymuszanie go samodzielnie. W drugim przypadku może działać dowolny język, który ma struktury i funkcje. Przychodzą mi na myśl dynamiczne języki i Haskell. Powiedziałbym, że po drugiej stronie spektrum nie ma wielu języków. Nawet C #, który jest naprawdę dobry w wymuszaniu enkapsulacji dla swoich obiektów, można ominąć za pomocą odbicia. Ale widzenie tego w C # byłoby uważane za ogromny zapach kodu i żaden rozsądny programista C # nie zrobiłby tego chętnie.
źródło