I.
Wprowadzenie do  języków zapytań (1)
II.
Wprowadzenie do  języków zapytań (2)
III.
Pojęcia obiektowości w bazach danych (1)
  Wstęp
  1. Co to jest obiektowość?
  2. Obiekt
  3. Metody związane z obiektem
  4. Obiekt złożony
  5. Relatywizm obiektów
  6. Zasada wewnętrznej identyfikacji
  7. Powiązania pomiędzy obiektami
  8. Hermetyzacja i ukrywanie informacji
  9. Mechanizm komunikatów
  Podsumowanie
  Zadania
IV.
Pojęcia obiektowości w bazach danych (2)
V.
Podstawy semantyczne języków zapytań
VI.
Modele składu obiektów
VII.
Stos środowisk, rezultaty zapytań, funkcja nested
VIII.
Język SBQL (Stack-Based Query Language) (1)
IX.
X.
Dalsze własności SBQL
XI.
Operatory order by i group by
XII.
Przetwarzanie struktur nieregularnych
XIII.
Rozszerzenie języków zapytań o konstrukcje imperatywne
XIV.
Procedury, procedury funkcyjne, metody, reguły zakresu
XV.
Parametry procedur i metod, procedury rekurencyjne, optymalizacja poprzez modyfikację zapytań

 

8. Hermetyzacja i ukrywanie informacji

Hermetyzacja (encapsulation) jest grupowaniem elementów składowych w obrębie jednej bryły i następnie umożliwienie manipulowania tą bryłą jako całością. Hermetyzację wiąże się z ukrywaniem części informacji dotyczącej struktury i implementacji wnętrza tej bryły (information hiding). Pojęcia hermetyzacji i ukrywania informacji są w zasadzie różne, ale są powszechnie ze sobą łączone. Dalej będziemy używać pojęcia hermetyzacji na oznaczenie konglomeratu obu pojęć.

Hermetyzacja nie jest wynalazkiem obiektowości i jest w stosunku do obiektowości do pewnego stopnia ortogonalna. Jest to generalna zasada inżynierii oprogramowania sformułowana przez D. Parnasa w 1972 w związku z zaproponowanym przez niego pojęciem modułu. Zasada hermetyzacji głosi, że programista ma tyle wiedzieć o tworze programistycznym (procedurze, module, obiekcie, klasie), ile mu trzeba, aby go efektywnie używać. Wszystko, co może być przed programistą ukryte, powinno być ukryte. Jest to pożądane zarówno ze względu na potrzebę nieprzeciążania modelu pojęciowego programisty niepotrzebnymi elementami, jak i ze względu na konieczność zredukowania potencjalnych źródeł błędów w oprogramowaniu. Specyfikacja bytu programistycznego powinna być oddzielona od implementacji ze względu na potrzebę uniezależnienia lokalnych zmian implementacyjnych od reszty oprogramowania. Oznacza to (w założeniu, które nie zawsze jest spełnione w satysfakcjonującym stopniu), że zmiany implementacji nie powinny wpływać na zewnętrzną semantykę danego obiektu programistycznego.

Programista używa obiektów na zasadzie czarnej skrzynki poprzez udostępnione operacje, często bez możliwości obejrzenia, co obiekty zawierają w środku, a tym bardziej bez możliwości zmiany ich wnętrza za pomocą środków innych niż udostępnione operacje. Hermetyzacja pozwala więc na bezpieczne użycie i obrót handlowy aktywami oprogramowania, takimi jak pakiety programów, biblioteki procedur, moduły i klasy. Z drugiej strony, hermetyzacja jest ważnym mechanizmem abstrakcji nawet w obrębie jednego programu i jednego programisty, gdyż pozwala mu na zamykanie szczegółów implementacyjnych w coraz większe bryły i dalsze operowanie tymi bryłami (poprzez udostępnione operacje) bez wnikania w ich wnętrze.

Hermetyzacja i ukrywanie informacji są podstawą istotnych pojęć w programowaniu, mianowicie pojęcia obiektu, klasy, modułu (który można uważać za odmianę obiektu) oraz abstrakcyjnego typu danych (abstract data type, ADT).

Hermetyzacja może być rozumiana w różny sposób, mianowicie:

  • Hermetyzacja ortodoksyjna (znana z języka Smalltalk i abstrakcyjnych typów danych). Na zewnątrz klasy lub obiektu widoczne są tylko metody lub operacje; natomiast pozostałe cechy obiektu (jego stan), w tym wszystkie jego atrybuty, są ukryte.

  • Hermetyzacja ortogonalna w stosunku do własności klasy, obiektu lub modułu (Modula-2, C++, Eiffel, Java). Dowolna własność obiektu (atrybut, metoda itp.) może być prywatna (ukryta) lub publiczna. Modula-2 i Eiffel wprowadzają pojęcie listy eksportowej, ustalającej cechy "eksportowane" na zewnątrz do użytku publicznego. C++ wprowadza podobny środek w inny sposób, jak również dodatkowe możliwości w postaci cech chronionych (protected) oraz klas "przyjacielskich" (friend class), co wytwarza pewną strefę pośrednią pomiędzy cechą całkowicie prywatną a cechą publiczną.


Wielu metodologów i zwolenników obiektowości pod pojęciem hermetyzacji implicite rozumie hermetyzację ortodoksyjną. Często powtarzanym argumentem na rzecz takiego rozumienia hermetyzacji jest uniezależnienie zewnętrznego interfejsu do obiektu od implementacji obiektu. Zdaniem tych autorów, jeżeli nie zezwoli się na bezpośredni dostęp do atrybutów obiektów, to operacje na obiektach będą bardziej bezpieczne. Co za tym idzie, postuluje się, aby każdy atrybut atr, który programista chciałby udostępnić publicznie, został wyposażony w dwie metody: czytaj_atr, która zwraca wartość atrybutu oraz zmień_atr, z parametrem w postaci nowej wartości atrybutu. Uzyskuje się w ten sposób kontrolowany dostęp do niektórych tylko komponentów obiektu.

Jakkolwiek podana argumentacja na rzecz ortodoksyjnej hermetyzacji pozornie wydaje się słuszna, można podać również szereg argumentów przeciwko takiemu rozumieniu tego pojęcia:

  • Niespójność z zasadą ortogonalności typów masowych. Np. załóżmy, że atrybutem atr pracownika jest zbiór jego stanowisk. W tym przypadku nie wystarczą nam metody czytaj_atrzmień_atr, ponieważ będą one działać na pełnych kolekcjach, natomiast programista może sobie życzyć odczytania pojedynczych elementów tych kolekcji, wstawiania nowych elementów i usuwania elementów. Często w takich sytuacjach argumentuje się, że można wprowadzić metody, takie jak daj_pierwszy, daj_następny, czy_ostatni, usuń_bieżący, wstaw_za_bieżącym itp. Semantyczna spójność takiej koncepcji oznacza, że niektóre z tych metod muszą zwrócić referencje do elementów kolekcji, zaś inne metody muszą z tych referencji korzystać. Referencje oznaczają umożliwienie bezpośredniego dostępu do wartości przechowywanej w ramach obiektu, czyli ewidentny wyłom w koncepcji ortodoksyjnej hermetyzacji. Typy masowe występujące wewnątrz obiektu oraz powiązania tego obiektu z innymi obiektami mogą także spowodować eksplozję ilości metod niezbędnych do ich obsługi.

  • Niespójność z zasadą relatywizmu obiektów. Zasada ta mówi, że atrybuty wewnątrz obiektu są również obiektami. Przyjmując konsekwentne stosowanie ortodoksyjnej hermetyzacji, wszelka obsługa tych atrybutów powinna być również dokonywana przez metody. Tymczasem obiekty atomowe muszą być obsługiwane przez wszyte w dany język metody generyczne (np. operator podstawienia), które wymagają referencji do takiego obiektu jako argumentu.

  • Niespójność z wartościami zerowymi i/lub wariantami. Jeżeli atrybut atr może przyjmować wartości zerowe lub może być obecny lub nieobecny w danym wariancie, wówczas podane wyżej dwie metody są niewystarczające.

  • Niespójność z koncepcją języków zapytań. Języki zapytań wymagają wiązania (czyli bezpośredniego dostępu) zarówno do obiektów, jak i ich atrybutów. Niespójność ta spowodowała powstanie poglądów uznających, że idea języków zapytań jest sprzeczna z obiektowością w bazach danych (np.[ Darw95, Date98]).

  • Niespójność z koncepcją schematu bazy danych. Programista programując aplikację z bazą danych musi widzieć i używać jej struktury w postaci obiektów, atrybutów i powiązań.

  • Ograniczenia koncepcyjne. Brak możliwości odzyskania referencji do wewnętrznych własności obiektów uniemożliwia napisanie pewnych procedur z parametrami komunikowanymi przez referencję, np. pojedynczej procedury zmieniającej wartość daty w dowolnym obiekcie. Ponadto ortodoksyjna hermetyzacja zajmuje się tylko dwoma rodzajami cech: atrybutami i metodami. Jak podamy później, takich cech może być więcej (np. powiązania, zdarzenia, obsługa zdarzeń), i wszystkie one mogą podlegać regułom hermetyzacji.


Jak wynika z przytoczonych argumentów, ortodoksyjna hermetyzacja jest w ogólnym przypadku poważnym ograniczeniem, szczególnie w obiektowych bazach danych. Niekiedy takie rozumienie hermetyzacji prowadzi wręcz do konkluzji stwierdzających, że dla baz danych hermetyzacja jest pozbawiona praktycznego sensu. Tego rodzaju poglądy głoszone przez znanych specjalistów mogą budzić zdumienie, zważywszy na fakt, że hermetyzacja jest podstawową zasadą nie tylko inżynierii oprogramowania, ale dowolnej inżynierii.

13
Rys.13. Hermetyzacja ortogonalna w stosunku do rodzaju cechy obiektu

Jedyną rozsądną alternatywą jest hermetyzacja ortogonalna taka, jaką zastosowano w Modula-2, gdzie dowolny byt programistyczny (zmienna, procedura, typ) może być wyeksportowany na zewnątrz modułu lub może być prywatny. Na Rys.13 pokazaliśmy taką właśnie hermetyzację obiektu PRACOWNIK: z zewnątrz tego obiektu są widoczne niektóre atrybuty i metody, zaś część tych atrybutów i metod pozostaje ukryta. Atrybuty udostępnione na zewnątrz mogą być obsługiwane wyłącznie przez operatory generyczne (generic) danego języka programowania, takie jak wiązanie (binding), dereferencja (dereferencing), podstawienie, tworzenie, wstawianie, usuwanie i wołanie poprzez referencję (call-by-reference). W takim rozumieniu hermetyzacji nie występują wymienione powyżej wady, a w szczególności, nie zachodzi sprzeczność pomiędzy hermetyzacją a językami zapytań.

Przyjęcie zasady hermetyzacji ortogonalnej wymaga istotnego założenia, mianowicie, że można odzyskać referencję dla dowolnych wyeksportowanych wartości (np. atrybutów) obiektu. Taka referencja jest zwracana przez operację wiązania nazwy atrybutu i następnie wykorzystywana przez środki ogólne danego języka, takie jak wspomniana operacja podstawienia. Inaczej mówiąc, każdy byt wyeksportowany na zewnątrz hermetyzowanej jednostki powinien mieć unikalny identyfikator. Ten aspekt bezpośrednio nawiązuje do omówionej wcześniej zasady wewnętrznej identyfikacji.

Copyrights © 2006 PJWSTK
Materiały zostały opracowane w PJWSTK w projekcie współfinansowanym ze środków EFS.