Padrão Singleton
Parte da seção Programação Orientada a Objetos do Journey de PHP da Coddy. Lição 71 de 91.
O Singleton Pattern é um padrão de projeto criacional que garante que uma classe tenha apenas uma instância durante todo o ciclo de vida da sua aplicação. Ele também fornece um ponto de acesso global a essa instância.
Este padrão é útil quando você precisa exatamente de um objeto para coordenar ações em todo o sistema, como uma conexão com o banco de dados, um gerenciador de configurações ou um logger. Criar várias instâncias desses objetos desperdiçaria recursos ou causaria um comportamento inconsistente.
Veja como implementar um Singleton em PHP:
<?php
class Database {
private static ?Database $instance = null;
private function __construct() {
// Construtor privado impede a instanciação direta
}
public static function getInstance(): Database {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function query(string $sql): string {
return "Executing: $sql";
}
}
$db1 = Database::getInstance();
$db2 = Database::getInstance();
echo $db1 === $db2 ? "Same instance" : "Different instances";
Saída:
Same instanceO padrão depende de três elementos principais: um construtor privado que impede o uso direto de new, uma propriedade estática que armazena a única instância e um método estático que cria a instância na primeira chamada e a retorna nas chamadas subsequentes.
Para tornar o Singleton realmente à prova de falhas, você também deve impedir a clonagem e a desserialização:
<?php
private function __clone() {}
public function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
Desafio
FácilVamos criar um gerenciador de configuração usando o Padrão Singleton. Em aplicações reais, normalmente você deseja uma única fonte de verdade para as configurações: ter vários objetos de configuração pode levar a comportamentos inconsistentes em todo o sistema.
Você organizará seu código em dois arquivos:
Config.php: crie uma classeConfigque implemente o Padrão Singleton. Seu gerenciador de configuração deve:- Armazenar as configurações em uma propriedade de array privada
- Ter um construtor privado que inicialize o array de configurações como vazio
- Fornecer um método estático
getInstance()que retorne a única instância - Impedir a clonagem tornando
__clone()privado - Incluir um método
set(string $key, string $value): voidpara armazenar uma configuração - Incluir um método
get(string $key): ?stringque retorne o valor de uma chave ounullcaso a chave não exista - Incluir um método
getAll(): arrayque retorne todas as configurações
main.php: inclua o arquivo Config. Você receberá duas entradas: uma chave e um valor.Obtenha a instância de Config e defina uma configuração padrão com a chave
"app_name"e o valor"MyApp".Obtenha uma segunda referência à instância de Config (usando
getInstance()novamente) e use-a para definir outra configuração usando a chave e o valor das entradas.Por fim, verifique se o Singleton está funcionando corretamente:
- Imprima
"Same instance: true"ou"Same instance: false"com base no fato de ambas as referências apontarem para o mesmo objeto (use===para comparar) - Imprima
"Settings count: [count]"mostrando o número total de configurações armazenadas (usecount()no resultado degetAll()) - Imprima
"App name: [value]"mostrando a configuração app_name recuperada por meio da segunda referência
- Imprima
Este desafio demonstra o principal benefício do Padrão Singleton: não importa quantas vezes você chame getInstance(), sempre obterá o mesmo objeto, garantindo que todas as partes da sua aplicação compartilhem o mesmo estado de configuração.
Experimente você mesmo
<?php
require_once 'Config.php';
// Ler entrada
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Obtenha a instância de Config e defina "app_name" como "MyApp"
// TODO: Obtenha uma segunda referência a Config usando getInstance() novamente
// TODO: Use a segunda referência para definir a configuração usando $key e $value da entrada
// TODO: Verifique se o Singleton está funcionando:
// - Print "Same instance: true" or "Same instance: false" based on === comparison
// - Print "Settings count: [count]" showing total settings
// - Imprima "App name: [value]" mostrando app_name obtido através da segunda referência
?>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 OOP
Arquivos externosIntrodução à OOPClasses vs. objetosA palavra-chave $thisMétodosPropriedadesConstrutor (__construct)Destrutor (__destruct)Recapitulação - Calculadora simples4Herança
Herança BásicaA Palavra-chave parent::Sobrescrita de MétodosA Palavra-chave finalClasses AbstratasRecapitulação - Hierarquia de Funcionários7Encapsulamento
Público, Protegido, PrivadoModificadores de Acesso em ProfundidadeGetters e SettersOcultação de InformaçõesPromoção de Construtor (8.0)Recapitulação - Sistema de Registros de Alunos10Conceitos Avançados de OOP
Composição vs. HerançaInjeção de DependênciaClasses AnônimasEnums (PHP 8.1)Fibras (PHP 8.1)Análise Profunda da 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 às InterfacesImplementando InterfacesImplementação de Múltiplas InterfacesInterface vs Classe AbstrataTipagem 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 NulosTipos de União e InterseçãoClasses de ExceçãoHierarquia de Exceções PersonalizadaTry, Catch, FinallyRecapitulação - Validador de Formulário14Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses de Livros e Usuários3Propriedades de Classes
Propriedades de Instância vs. EstáticasConstantes em ClassesMétodos e Propriedades EstáticosPropriedades Privadas e ProtegidasPropriedades Somente para Leitura (PHP 8.1)Recapitulação - Gerenciador de Contas Bancárias6Polimorfismo
Revisão da Sobrescrita de MétodosPolimorfismo via InterfacesIndicação de Tipos e Tipos UnionVinculação Estática TardiaRecapitulação - Processador de Pagamentos9Traits
Introdução a TraitsUsando Múltiplos TraitsResolução de Conflitos entre 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 StrategyPratique por conta própria: Compilador de PHP online