Menu
Coddy logo textTech

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 instance

O 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");
}
challenge icon

Desafio

Fácil

Vamos 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 classe Config que 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): void para armazenar uma configuração
    • Incluir um método get(string $key): ?string que retorne o valor de uma chave ou null caso a chave não exista
    • Incluir um método getAll(): array que 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 (use count() no resultado de getAll())
    • Imprima "App name: [value]" mostrando a configuração app_name recuperada por meio da segunda referência

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

?>
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

Pratique por conta própria: Compilador de PHP online