JavaRush /Курси /Frontend SELF UA /Інкапсуляція

Інкапсуляція

Frontend SELF UA
Рівень 40 , Лекція 2
Відкрита

9.1 Основні концепції

Інкапсуляція — це одна з ключових концепцій об'єктно-орієнтованого програмування (ООП), яка дозволяє приховувати внутрішні деталі реалізації об'єкта та надавати доступ до цих деталей через строго визначені інтерфейси. Це допомагає покращити безпеку та спрощує управління кодом.

Переваги інкапсуляції:

  1. Приховування даних: інкапсуляція дозволяє приховувати внутрішні деталі реалізації та надавати доступ тільки до необхідних методів і властивостей. Це запобігає некоректному використанню об'єктів та покращує безпеку коду.
  2. Контроль доступу: інкапсуляція дозволяє контролювати доступ до даних і методів, надаючи можливість змінювати внутрішній стан об'єкта лише через певні методи.
  3. Підтримуваність: інкапсуляція покращує підтримку коду, оскільки зміни в реалізації не впливають на зовнішній інтерфейс класу. Це дозволяє вносити зміни в реалізацію без зміни коду, що використовує клас.
  4. Покращення тестування: інкапсуляція дозволяє ізолювати внутрішню реалізацію об'єкта, що спрощує модульне тестування та зменшує ймовірність виникнення побічних ефектів.

У JavaScript інкапсуляція реалізується за допомогою методів і властивостей, а починаючи з ES2022, також стали доступними приватні поля та методи.

9.2 Інкапсуляція через замикання

До введення приватних полів в ES2022, інкапсуляція в JavaScript часто досягалася з використанням замикань.

Приклад:

  • Змінна count доступна тільки всередині функції createCounter і недоступна ззовні
  • Методи increment, decrement і getCount можуть взаємодіяти з приватною змінною count
JavaScript
    
      function createCounter() {
        let count = 0; // приватна змінна

        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 Приватні поля в ES2022

У ES2022 були введені приватні поля та методи, які оголошуються з використанням символу #. Приватні поля та методи не можуть бути доступні чи змінені ззовні класу.

Приклад:

  • Приватні поля #name і #age оголошені з використанням символу #
  • Методи getName, getAge, setName і setAge дозволяють взаємодіяти з приватними полями
  • Спроба доступу до приватних полів ззовні класу призводить до помилки
JavaScript
    
      class Person {
        #name; // приватне поле
        #age; // приватне поле

        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); // Помилка: приватне поле недоступне
    
  

9.4 Приватні методи

Приватні методи також можуть бути оголошені з використанням символу # і бути недоступними ззовні класу.

Приклад:

  • Приватне поле #balance та приватний метод #logTransaction використовуються для управління станом об'єкта BankAccount
  • Приватний метод #logTransaction викликається всередині публічних методів deposit і withdraw для запису транзакцій
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); // Помилка: приватний метод недоступний
    
  
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ