Menu
Coddy logo textTech

Ocultação de Informação

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 34 de 110.

Ocultação de informações é o princípio por trás do encapsulamento - a ideia de que uma classe deve esconder seu funcionamento interno e expor apenas o que é necessário. Você aprendeu a mecânica (campos privados, getters, setters), mas o objetivo real é projetar classes que sejam fáceis de usar e difíceis de usar incorretamente.

Considere uma classe que gerencia a senha de um usuário. O armazenamento interno e a lógica de hashing devem ser completamente ocultos:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';  // Exemplo simplificado
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

O código externo nunca vê o hash da senha ou sabe como ele é armazenado. Eles simplesmente chamam verifyPassword(). Essa separação significa que você poderia alterar completamente o algoritmo de hashing sem afetar nenhum código que use esta classe.

O insight fundamental é pensar sobre sua classe de fora para dentro.

Pergunte a si mesmo: "O que alguém que utiliza esta classe realmente precisa?" Exponha apenas isso e mantenha todo o resto privado. Isso cria uma fronteira clara entre o que sua classe faz (sua interface pública) e como ela faz (sua implementação privada).

challenge icon

Desafio

Fácil

Vamos construir um sistema de carteira segura que demonstra a ocultação de informações em ação. Você criará uma carteira digital que gerencia o saldo e o histórico de transações de um usuário, mantendo todos os detalhes internos sensíveis completamente ocultos do código externo.

Você organizará seu código em dois arquivos:

  • wallet.dart: Crie uma classe Wallet que gerencie dinheiro de forma segura. A carteira deve armazenar o nome do proprietário publicamente, mas todo o resto deve estar oculto atrás de uma interface pública limpa:
    • O saldo interno e o log de transações devem ser privados - o código externo nunca deve ver como você armazena ou rastreia o dinheiro
    • Um método privado deve lidar com o registro de transações internamente (armazenando entradas como "Deposit: $50.0" ou "Withdrawal: $30.0")
    • Forneça um método público deposit(double amount) que adiciona dinheiro (apenas se o valor for positivo) e registra a transação internamente
    • Forneça um método público withdraw(double amount) que remove dinheiro apenas se houver fundos suficientes e o valor for positivo, registrando a transação internamente. Retorne true se for bem-sucedido, false caso contrário
    • Forneça um getter público balance que retorna o saldo atual (acesso somente leitura)
    • Forneça um método público getTransactionCount() que retorna quantas transações foram registradas (sem expor a lista de transações real)
    • Forneça um método público getLastTransaction() que retorna a string da transação mais recente, ou "No transactions" se nenhuma existir
    • Inclua um método printSummary() que exibe o status da carteira
  • main.dart: Importe sua carteira e demonstre como a ocultação de informações cria uma interface limpa e segura:
    • Crie uma carteira para o proprietário "Sarah"
    • Deposite 100.0
    • Deposite 50.0
    • Tente sacar 200.0 e imprima "Withdrawal of 200.0: [success/failed]" com base no resultado
    • Saque 30.0 e imprima "Withdrawal of 30.0: [success/failed]"
    • Chame printSummary()
    • Imprima "Transaction count: [count]"
    • Imprima "Last transaction: [transaction]"

O método printSummary() deve imprimir:

=== Wallet Summary ===
Owner: [ownerName]
Balance: $[balance]

Observe como o código externo pode interagir com a carteira por meio de métodos claros e objetivos, sem nunca saber como o saldo é armazenado ou como as transações são rastreadas internamente. Os detalhes de implementação estão completamente ocultos - você poderia alterar como as transações são armazenadas sem afetar nenhum código que use a carteira.

Saída esperada:

Withdrawal of 200.0: failed
Withdrawal of 30.0: success
=== Wallet Summary ===
Owner: Sarah
Balance: $120.0
Transaction count: 3
Last transaction: Withdrawal: $30.0

Folha de consulta

A ocultação de informações é o princípio por trás do encapsulamento - esconder o funcionamento interno de uma classe e expor apenas o que é necessário.

Projete classes de fora para dentro: exponha apenas o que os usuários precisam, mantenha todo o resto privado. Isso cria um limite claro entre a interface pública (o que a classe faz) e a implementação privada (como ela faz).

Exemplo de ocultação de informações com um gerenciador de senhas:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

O código externo nunca vê o hash da senha ou o mecanismo de armazenamento - ele apenas usa verifyPassword(). Isso permite alterar a implementação interna sem afetar o código externo.

Experimente você mesmo

import 'wallet.dart';

void main() {
  // TODO: Criar uma carteira para a proprietária "Sarah"
  
  // TODO: Depositar 100.0
  
  // TODO: Depositar 50.0
  
  // TODO: Tentar sacar 200.0 e imprimir o resultado
  // Formato: "Withdrawal of 200.0: [success/failed]"
  
  // TODO: Sacar 30.0 e imprimir o resultado
  // Formato: "Withdrawal of 30.0: [success/failed]"
  
  // TODO: Chamar printSummary()
  
  // TODO: Imprimir a contagem de transações
  // Formato: "Transaction count: [count]"
  
  // TODO: Imprimir a última transação
  // Formato: "Last transaction: [transaction]"
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos