Đóng gói

Frontend SELF VI
Mức độ , Bài học
Có sẵn

9.1 Khái niệm cơ bản

Đóng gói - đây là một trong những khái niệm chính của lập trình hướng đối tượng (OOP), giúp ẩn đi những chi tiết bên trong của việc triển khai đối tượng và cung cấp quyền truy cập vào những chi tiết này qua các giao diện xác định rõ ràng. Điều này giúp cải thiện bảo mật và đơn giản hóa việc quản lý mã.

Lợi ích của đóng gói:

  1. Ẩn dữ liệu: đóng gói cho phép ẩn đi các chi tiết triển khai bên trong và chỉ cung cấp quyền truy cập vào các phương thức và thuộc tính cần thiết. Điều này ngăn chặn việc sử dụng sai đối tượng và cải thiện bảo mật của mã.
  2. Kiểm soát truy cập: đóng gói cho phép kiểm soát quyền truy cập vào dữ liệu và phương thức, cho phép thay đổi trạng thái bên trong của đối tượng chỉ qua các phương thức xác định.
  3. Dễ bảo trì: đóng gói cải thiện khả năng hỗ trợ mã vì các thay đổi trong việc triển khai không ảnh hưởng đến giao diện bên ngoài của lớp. Điều này cho phép thực hiện thay đổi trong việc triển khai mà không cần thay đổi mã sử dụng lớp.
  4. Cải thiện kiểm thử: đóng gói cho phép cô lập việc triển khai bên trong của đối tượng, giúp dễ dàng kiểm thử đơn vị và giảm thiểu khả năng xảy ra tác dụng phụ.

Trong JavaScript, đóng gói được thực hiện bằng cách sử dụng phương thức và thuộc tính, và bắt đầu từ ES2022, cũng đã có các trường và phương thức riêng tư.

9.2 Đóng gói qua closures

Trước khi có các trường riêng tư trong ES2022, đóng gói trong JavaScript thường được thực hiện qua closures.

Ví dụ:

  • Biến count chỉ có thể truy cập được bên trong hàm createCounter và không thể truy cập từ bên ngoài
  • Các phương thức increment, decrementgetCount có thể tương tác với biến riêng tư count
JavaScript
    
      function createCounter() {
        let count = 0; // biến riêng tư

        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 Trường riêng tư trong ES2022

Trong ES2022, đã có trường và phương thức riêng tư, được khai báo bằng cách sử dụng ký hiệu #. Trường và phương thức riêng tư không thể truy cập hoặc thay đổi từ bên ngoài lớp.

Ví dụ:

  • Các trường riêng tư #name#age được khai báo bằng ký hiệu #
  • Các phương thức getName, getAge, setNamesetAge cho phép tương tác với các trường riêng tư
  • Thử truy cập vào các trường riêng tư từ bên ngoài lớp sẽ gây lỗi
JavaScript
    
      class Person {
        #name; // trường riêng tư
        #age; // trường riêng tư

        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); // Lỗi: trường riêng tư không truy cập được
    
  

9.4 Phương thức riêng tư

Phương thức riêng tư cũng có thể được khai báo bằng cách sử dụng ký hiệu # và không thể truy cập từ bên ngoài lớp.

Ví dụ:

  • Trường riêng tư #balance và phương thức riêng tư #logTransaction được sử dụng để quản lý trạng thái của đối tượng BankAccount
  • Phương thức riêng tư #logTransaction được gọi bên trong các phương thức công khai depositwithdraw để ghi lại các giao dịch
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); // Lỗi: phương thức riêng tư không truy cập được
    
  
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION