Encapsulamento

Frontend SELF PT
Nível 40 , Lição 2
Disponível

9.1 Conceitos Básicos

Encapsulamento é um dos conceitos-chave na programação orientada a objetos (POO) que permite esconder os detalhes internos da implementação de um objeto e fornecer acesso a esses detalhes por meio de interfaces bem definidas. Isso ajuda a melhorar a segurança e simplifica a gestão do código.

Vantagens do encapsulamento:

  1. Ocultação de dados: o encapsulamento permite esconder os detalhes internos da implementação e fornecer acesso apenas aos métodos e propriedades necessários. Isso evita o uso incorreto de objetos e melhora a segurança do código.
  2. Controle de acesso: o encapsulamento permite controlar o acesso aos dados e métodos, permitindo que o estado interno do objeto seja alterado apenas por meio de métodos específicos.
  3. Manutenibilidade: o encapsulamento melhora a manutenção do código, já que mudanças na implementação não afetam a interface externa da classe. Isso permite fazer alterações na implementação sem alterar o código que usa a classe.
  4. Melhoria nos testes: o encapsulamento permite isolar a implementação interna do objeto, o que facilita o teste unitário e reduz a probabilidade de efeitos colaterais.

No JavaScript, o encapsulamento é realizado usando métodos e propriedades, e a partir do ES2022, também se tornaram disponíveis campos e métodos privados.

9.2 Encapsulamento por meio de closures

Antes da introdução de campos privados no ES2022, o encapsulamento no JavaScript era frequentemente alcançado usando closures.

Exemplo:

  • A variável count está disponível apenas dentro da função createCounter e não está acessível externamente
  • Os métodos increment, decrement e getCount podem interagir com a variável privada count
JavaScript
    
      function createCounter() {
        let count = 0; // variável privada

        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 Campos Privados no ES2022

No ES2022, foram introduzidos campos e métodos privados, que são declarados usando o símbolo #. Campos e métodos privados não podem ser acessados ou modificados externamente à classe.

Exemplo:

  • Os campos privados #name e #age são declarados usando o símbolo #
  • Os métodos getName, getAge, setName e setAge permitem interagir com os campos privados
  • Tentar acessar os campos privados externamente à classe resulta em erro
JavaScript
    
      class Person {
        #name; // campo privado
        #age; // campo privado

        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); // Erro: campo privado não acessível
    
  

9.4 Métodos Privados

Métodos privados também podem ser declarados usando o símbolo # e não podem ser acessados externamente à classe.

Exemplo:

  • O campo privado #balance e o método privado #logTransaction são usados para gerenciar o estado do objeto BankAccount
  • O método privado #logTransaction é chamado dentro dos métodos públicos deposit e withdraw para registrar transações
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); // Erro: método privado não acessível
    
  
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION