Ogólnie

 

To jest właśnie to, czego uczyliśmy się na zajęciach u dr. Gwizdałły. "Oblekanie" klas w funkcje typu Get oraz Set, żeby hakerzy się ne włamali. Poniżej definicja, przykład na którym będzie oparte to opracowanie oraz przyczyny stosowania hermetyzacji.

Definicja hermetyzacji

 

Hermetyzacja (z ang. encapsulation, kapsułkowanie, ukrywanie informacji, czasami także enkapsulacja) – jedno z założeń paradygmatu programowania obiektowego. Polega ono na ukrywaniu pewnych danych składowych lub metod obiektów danej klasy tak, aby były one (i ich modyfikacja) dostępne tylko metodom wewnętrznym danej klasy lub funkcjom z nią zaprzyjaźnionym.

Z pełną hermetyzacją mamy do czynienia wtedy, gdy dostęp do wszystkich pól w klasie jest możliwy tylko i wyłącznie poprzez metody, lub inaczej mówiąc gdy wszystkie pola w klasie znajdują się w sekcji prywatnej (lub chronionej).

Definicja bardziej opisowa:

Ukrywanie implementacji, enkapsulacja. Zapewnia, że obiekt nie może zmieniać stanu wewnętrznego innych obiektów w nieoczekiwany sposób. Tylko wewnętrzne metody obiektu są uprawnione do zmiany jego stanu. Każdy typ obiektu prezentuje innym obiektom swój interfejs, który określa dopuszczalne metody współpracy. Pewne języki osłabiają to założenie, dopuszczając pewien poziom bezpośredniego (kontrolowanego) dostępu do "wnętrzności" obiektu. Ograniczają w ten sposób poziom abstrakcji. Przykładowo, w niektórych kompilatorach języka C++ istnieje możliwość tymczasowego wyłączenia mechanizmu enkapsulacji; otwiera to dostęp do wszystkich pól i metod prywatnych, ułatwiając programistom pracę nad pośrednimi etapami tworzenia kodu i znajdowaniem błędów.

Ukrywanie wewnętrznej struktury obiektu jest bardzo ważne z kilku powodów. Po pierwsze, obiekt taki jest odizolowany, a więc nie jest narażony na celowe, bądź niezamierzone działanie ze strony użytkownika. Po drugie, obiekt ten na pewno jest chroniony od niepożądanych referencji ze strony innych obiektów. Po trzecie, obiekt taki – jeśli jest to tylko możliwe, nie wpływa na zmiany, czy jakieś małe korekty wprowadzone w implementacji. Po prostu obie strony nie kolidują wówczas ze sobą. I po czwarte, dzięki ukryciu wewnętrznej struktury obiektu, można uzyskać jego przenośność. Innymi słowy, zastosować definiującą go klasę w innym fragmencie kodu, czy też programie.

Przykład w C++

 

 typedef double TypPieniedzy;
 
 class KontoBankowe {
   public:
     KontoBankowe( const TypPieniedzy saldoPoczatkowe = 0 );
     bool wplac( const TypPieniedzy kwota );
     bool wyplac( const TypPieniedzy kwota );
     TypPieniedzy podajStanKonta() const;
   private:
     TypPieniedzy saldo;
 };
 
 KontoBankowe::KontoBankowe( const TypPieniedzy saldoPoczatkowe) 
   :
   saldo( saldoPoczatkowe )
   {
 }
  bool KontoBankowe::wplac( const TypPieniedzy kwota ) {
   if ( kwota > 0 ) {
     saldo += kwota;
     return true;
   }
   return false;
 }
 
 bool KontoBankowe::wyplac( const TypPieniedzy kwota ) {
   // Powiększenie kwoty o 10% prowizji.
   TypPieniedzy kwotaProw = kwota*1.1;
   if ( ( kwotaProw > 0 ) && ( kwotaProw >= saldo ) ) {
       saldo -= kwotaProw;
       return true;
   }
   return false;
 }
 
 TypPieniedzy KontoBankowe::podajStanKonta() const {
   return saldo;
 }

Przyczyny stosowania hermetyzacji

 

  • Uodparnia tworzony model na błędy
    Hermetyzacja uodparnia tworzony model na błędy polegające np. na błędnym przypisywaniu wartości oraz umożliwia wykonanie czynności pomocniczych (jak np. pobranie z konta 10% wypłacanej kwoty jako prowizji) lub obsługę sytuacji wyjątkowej (np. brak wymaganych środków).

    Mamy klasę KontoBankowe. Nie powinno się tak zdarzyć, że stan konta mógłby być modyfikowany przez zwykłe odwołanie się do danej saldo (np.: mojeKonto.saldo = 123;). Tu saldo konta bankowego jest daną chronioną (dostęp jest private), do której dostęp mają tylko funkcje zaprzyjaźnione lub funkcje składowe (wewnętrzne) (tu: podajStanKonta, wplac i wyplac). Powinno się zapewnić maksymalne bezpieczeństwo w odniesieniu do danej saldo. Stąd też metoda TypPieniedzy podajStanKonta() jest oznaczona jako const, wartość kwoty w metodach bool wplac( const TypPieniedzy kwota ) i bool wyplac( const TypPieniedzy kwota ) jest określona również jako const aby jej wartość nie została „przypadkiem” zmieniona w trakcie działania tych metod.

    Hermetyzacja ma też na celu sprawdzanie poprawności wpisywanych danych (czy powinno się dać wpłacić na konto kwoty będącej wartością ujemną?).

  • Lepiej oddaje rzeczywistość
    W powyższym przykładzie obrazuje atomowe operacje na koncie bankowym, podczas gdy odwołanie się bezpośrednie do salda nie oznaczałoby nic szczególnego.

  • Umożliwia rozbicie modelu na mniejsze elementy
    Dzięki stosowaniu hermetyzacji można budować modele rzeczywistości jako struktury składające z mniejszych modułów, z których każdy ma pewne określone dane i określone metody wpływania na ich stan i sprawdzania go. Na przykład w tworzeniu modelu samochodu można użyć modułu silnika, który ma określony szereg danych wewnętrznych (np. opisujących jego stan w trakcie pracy) i metod wewnętrznych (np. pobranie paliwa, wywołanie reakcji, ruch wirnika). Wszystko to jednak jest nieistotne dla użytkownika (a nawet nie powinno być dostępne), który ma możliwość użycia tylko zapłonu i wyłączenia silnika.