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ę
Hermetyzacja to koncepcja, która łączy dane i funkcje, które manipulują danymi ...
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:
... i to chroni zarówno przed ingerencją z zewnątrz, jak i niewłaściwym użyciem.
Wikipedia zgadza się również, że:
Mechanizm językowy do ograniczania bezpośredniego dostępu do niektórych składników obiektu.
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 jedno stringpole. Mamy wymagania, że jeśli masz wartość typu, Emailto pole zawiera prawidłowy adres. W enkapsulacji OOP można to łatwo zrobić, deklarując to pole private, podając tylko Getmetodę i mającconstructor methodudaje 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.