Enkapsulacja

Frontend SELF PL
Poziom 40 , Lekcja 2
Dostępny

9.1 Główne pojęcia

Enkapsulacja — to jedna z kluczowych koncepcji programowania obiektowego (OOP), która pozwala ukrywać wewnętrzne szczegóły implementacji obiektu i zapewniać dostęp do tych szczegółów przez ściśle określone interfejsy. Pomaga to poprawić bezpieczeństwo i uprościć zarządzanie kodem.

Zalety enkapsulacji:

  1. Ukrywanie danych: enkapsulacja pozwala ukrywać wewnętrzne szczegóły implementacji i zapewniać dostęp tylko do niezbędnych metod i właściwości. To zapobiega niepoprawnemu używaniu obiektów i poprawia bezpieczeństwo kodu.
  2. Kontrola dostępu: enkapsulacja pozwala kontrolować dostęp do danych i metod, dając możliwość zmieniania wewnętrznego stanu obiektu tylko przez określone metody.
  3. Wspieralność: enkapsulacja poprawia wsparcie kodu, ponieważ zmiany w implementacji nie wpływają na zewnętrzny interfejs klasy. Pozwala to na wprowadzanie zmian w implementacji bez zmieniania kodu, który używa klasy.
  4. Poprawa testowania: enkapsulacja pozwala izolować wewnętrzną implementację obiektu, co upraszcza testy jednostkowe i zmniejsza prawdopodobieństwo powstawania efektów ubocznych.

W JavaScript enkapsulacja jest realizowana przy użyciu metod i właściwości, a począwszy od ES2022, dostępne są również pola i metody prywatne.

9.2 Enkapsulacja przez domknięcia

Przed wprowadzeniem prywatnych pól w ES2022, enkapsulacja w JavaScript często osiągana była za pomocą domknięć.

Przykład:

  • Zmienna count jest dostępna tylko wewnątrz funkcji createCounter i niedostępna z zewnątrz
  • Metody increment, decrement i getCount mogą interakcjonować z prywatną zmienną count
JavaScript
    
      function createCounter() {
        let count = 0; // prywatna zmienna

        return {
          increment() {
            count++;
            console.log(count);
          },
          decrement() {
            count--;
            console.log(count);
          },
          getCount() {
            return count;
          }
        };
      }

      const counter = createCounter();
      counter.increment(); // 1
      counter.increment(); // 2
      console.log(counter.getCount()); // 2
      counter.decrement(); // 1
    
  

9.3 Pola prywatne w ES2022

W ES2022 wprowadzono pola i metody prywatne, które deklaruje się przy użyciu symbolu #. Pola i metody prywatne nie mogą być dostępne ani zmieniane poza klasą.

Przykład:

  • Pola prywatne #name i #age są deklarowane przy użyciu symbolu #
  • Metody getName, getAge, setName i setAge pozwalają na interakcję z polami prywatnymi
  • Próba dostępu do pól prywatnych spoza klasy prowadzi do błędu
JavaScript
    
      class Person {
        #name; // pole prywatne
        #age; // pole prywatne

        constructor(name, age) {
          this.#name = name;
          this.#age = age;
        }

        getName() {
          return this.#name;
        }

        getAge() {
          return this.#age;
        }

        setName(name) {
          this.#name = name;
        }

        setAge(age) {
          if (age > 0) {
            this.#age = age;
          }
        }
      }

      const person = new Person('Alice', 30);
      console.log(person.getName()); // "Alice"
      console.log(person.getAge()); // 30
      person.setName('Bob');
      person.setAge(25);
      console.log(person.getName()); // "Bob"
      console.log(person.getAge()); // 25

      console.log(person.#name); // Błąd: pole prywatne jest niedostępne
    
  

9.4 Metody prywatne

Metody prywatne również mogą być deklarowane przy użyciu symbolu # i być niedostępne spoza klasy.

Przykład:

  • Pole prywatne #balance i prywatna metoda #logTransaction są używane do zarządzania stanem obiektu BankAccount
  • Prywatna metoda #logTransaction jest wywoływana wewnątrz publicznych metod deposit i withdraw do rejestrowania transakcji
JavaScript
    
      class BankAccount {
        #balance;

        constructor(initialBalance) {
          this.#balance = initialBalance;
        }

        deposit(amount) {
          if (amount > 0) {
            this.#balance += amount;
            this.#logTransaction('deposit', amount);
          }
        }

        withdraw(amount) {
          if (amount > 0 && amount <= this.#balance) {
            this.#balance -= amount;
            this.#logTransaction('withdraw', amount);
          }
        }

        getBalance() {
          return this.#balance;
        }

        #logTransaction(type, amount) {
          console.log(`Transaction: ${type} ${amount}`);
        }
      }

      const account = new BankAccount(1000);
      account.deposit(500); // "Transaction: deposit 500"
      console.log(account.getBalance()); // 1500
      account.withdraw(200); // "Transaction: withdraw 200"
      console.log(account.getBalance()); // 1300

      account.#logTransaction('test', 100); // Błąd: metoda prywatna jest niedostępna
    
  
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION