Ocultação de Informação
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy — lição 41 de 91.
Ocultação de informações é o princípio por trás do encapsulamento - a ideia de que uma classe deve expor apenas o que é necessário e esconder seus detalhes de implementação interna. Enquanto modificadores de acesso e getters/setters são as ferramentas, a ocultação de informações é a filosofia de design que guia como você as utiliza.
O objetivo é criar uma fronteira clara entre o que uma classe faz (sua interface pública) e como ela faz (sua implementação interna). Essa separação significa que você pode alterar o funcionamento interno sem afetar o código que utiliza a classe:
<?php
class Temperature {
private float $celsius;
public function setCelsius(float $value): void {
$this->celsius = $value;
}
public function getCelsius(): float {
return $this->celsius;
}
public function getFahrenheit(): float {
return ($this->celsius * 9/5) + 32;
}
}
$temp = new Temperature();
$temp->setCelsius(25);
echo $temp->getCelsius() . "C = " . $temp->getFahrenheit() . "F";
Saída:
25C = 77FA classe armazena a temperatura internamente em Celsius, mas os usuários não precisam saber disso. Você poderia alterar posteriormente o armazenamento interno para Fahrenheit ou Kelvin e, desde que os métodos públicos continuem funcionando da mesma forma, nenhum código externo será quebrado.
Ponto Chave: O ocultamento de informações protege seu código de mudanças. Esconda detalhes de implementação, exponha apenas interfaces estáveis, e suas classes se tornarão mais fáceis de manter e modificar ao longo do tempo.
Desafio
FácilVamos construir um conversor de moedas que demonstra a ocultação de informações em ação. Você criará uma classe que armazena dinheiro internamente em uma moeda, mas que pode converter perfeitamente de e para várias moedas — sem que o código externo saiba como os dados são realmente armazenados.
Você organizará seu código em dois arquivos:
Money.php— Crie uma classeMoneyque armazena internamente todos os valores em centavos (como um número inteiro) para evitar problemas de precisão de ponto flutuante. Este detalhe de implementação deve ser completamente ocultado dos usuários da classe. A classe deve fornecer:- Uma propriedade privada para armazenar o valor em centavos
setDollars(float $amount)— aceita um valor em dólares e o armazena internamente como centavosgetDollars()— retorna o valor em dólares (float, 2 casas decimais)setEuros(float $amount)— aceita euros e os converte em centavos usando a taxa: 1 EUR = 1.10 USDgetEuros()— retorna o valor convertido para euros (float, 2 casas decimais)getInternalValue()— retorna o valor bruto em centavos (inteiro) para fins de depuração
main.php— Inclua o arquivo Money. Você receberá duas entradas: um valor em dólares e um valor em euros. Crie uma instância deMoney. Primeiro, defina o valor em dólares (convertido para float) e imprima três linhas: o valor em dólares, o equivalente em euros e o valor interno em centavos. Em seguida, defina o valor em euros (convertido para float) e imprima os mesmos três valores novamente.
A beleza deste design é que o código externo trabalha com valores familiares de dólares e euros, completamente alheio ao fato de que tudo é armazenado como centavos internamente. Você poderia, mais tarde, alterar o armazenamento interno para usar uma moeda base diferente ou uma estratégia de precisão diferente e, desde que os métodos públicos continuem a funcionar corretamente, nenhum código externo precisaria ser alterado.
Formate todas as saídas de dólares e euros com exatamente 2 casas decimais. Cada valor deve ser impresso em sua própria linha, resultando em seis linhas de saída no total.
Folha de consulta
O ocultamento de informações é o princípio por trás do encapsulamento - expondo apenas o que é necessário enquanto oculta os detalhes da implementação interna. Isso cria um limite claro entre o que uma classe faz (interface pública) e como ela faz (implementação interna).
Exemplo de ocultamento de informações com uma classe Temperature:
<?php
class Temperature {
private float $celsius;
public function setCelsius(float $value): void {
$this->celsius = $value;
}
public function getCelsius(): float {
return $this->celsius;
}
public function getFahrenheit(): float {
return ($this->celsius * 9/5) + 32;
}
}
$temp = new Temperature();
$temp->setCelsius(25);
echo $temp->getCelsius() . "C = " . $temp->getFahrenheit() . "F";
// Saída: 25C = 77F
A classe armazena a temperatura internamente em Celsius, mas os usuários não precisam saber disso. O armazenamento interno poderia ser alterado para Fahrenheit ou Kelvin sem quebrar o código externo, desde que os métodos públicos continuem a funcionar da mesma maneira.
Principais benefícios: O ocultamento de informações protege o código de alterações. Ao ocultar detalhes de implementação e expor apenas interfaces estáveis, as classes tornam-se mais fáceis de manter e modificar ao longo do tempo.
Experimente você mesmo
<?php
require_once 'Money.php';
// Ler entradas
$dollarAmount = floatval(trim(fgets(STDIN)));
$euroAmount = floatval(trim(fgets(STDIN)));
// TODO: Criar uma instância de Money
// TODO: Definir o valor em dólares e imprimir:
// - O valor em dólares (2 casas decimais)
// - O equivalente em euros (2 casas decimais)
// - O valor interno em centavos (inteiro)
// TODO: Definir o valor em euros e imprimir:
// - O valor em dólares (2 casas decimais)
// - O equivalente em euros (2 casas decimais)
// - O valor interno em centavos (inteiro)
?>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
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosA Palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodoA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em DetalhesGetters e SettersOcultação de InformaçãoPromoção de Construtor (8.0)Recapitulação - Sistema de Registro de Alunos10Conceitos Avançados de POO
Composição vs HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibers (PHP 8.1)Mergulho Profundo em Clonagem de ObjetosGeradores e Iteradores13Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão CompositePadrão Repository2Namespaces e Autoloading
Introdução a NamespacesA Palavra-chave usePadrão de Autoloading PSR-4Autoloader do ComposerRecapitulação - Projeto Organizado5Interfaces e Contratos
Introdução a InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataType Hinting com InterfacesRecapitulação - Calculadora de Formas8Métodos Mágicos
Introdução aos Métodos Mágicos__toString e __debugInfo__get, __set, __isset, __unset__call e __callStatic__clone e Clonagem de Objetos__serialize e __unserializeRecapitulação - Coleção Personalizada11Sistema de Tipos e Tratamento de Erros
Declarações de TiposTipos AnuláveisTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadasTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário3Propriedades de Classe
Propriedades de Instância vs EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Readonly (PHP 8.1)Recapitulação - Gerenciador de Conta Bancária6Polimorfismo
Sobrescrita de Métodos RevisitadaPolimorfismo via InterfacesType Hinting e Union TypesLate Static BindingRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos de TraitsMétodos Abstratos em TraitsTraits vs Herança12Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy