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 Padrão Singleton é 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 de exatamente um objeto para coordenar ações em todo o sistema, como uma conexão de banco de dados, gerenciador de configuração ou logger. Criar múltiplas instâncias destes 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() {
        // O 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 baseia-se em três elementos-chave: um construtor privado que impede o uso de new diretamente, uma propriedade estática que mantém a instância única, e um método estático que cria a instância na primeira chamada e a retorna em chamadas subsequentes.

Para tornar o Singleton verdadeiramente à prova de balas, 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 construir um gerenciador de configurações usando o Singleton Pattern. Em aplicações reais, você geralmente deseja uma única fonte de verdade para as definições de configuração — ter múltiplos objetos de configuração poderia levar a um comportamento inconsistente em todo o seu sistema.

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

  • Config.php — Crie uma classe Config que implemente o Singleton Pattern. Seu gerenciador de configurações deve:
    • Armazenar as configurações em uma propriedade de array privada
    • Ter um construtor privado que inicializa o array de configurações como vazio
    • Fornecer um método estático getInstance() que retorna a instância única
    • Impedir a clonagem tornando o método __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 retorna o valor para uma chave, ou null se a chave não existir
    • Incluir um método getAll(): array que retorna 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 para a instância de Config (usando getInstance() novamente) e use-a para definir outra configuração usando a chave e o valor das entradas.

    Finalmente, 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 através da segunda referência

Este desafio demonstra o benefício central do Singleton Pattern: não importa quantas vezes você chame getInstance(), você sempre obtém o mesmo objeto, garantindo que todas as partes da sua aplicação compartilhem o mesmo estado de configuração.

Folha de consulta

O Padrão Singleton garante que uma classe tenha apenas uma instância durante todo o ciclo de vida da sua aplicação e fornece um ponto de acesso global a essa instância.

Este padrão é útil para objetos como conexões de banco de dados, gerenciadores de configuração ou loggers, onde múltiplas instâncias desperdiçariam recursos ou causariam comportamento inconsistente.

Implementação básica de Singleton:

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // O construtor privado impede a instanciação direta
    }
    
    public static function getInstance(): Database {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$db1 = Database::getInstance();
$db2 = Database::getInstance();

echo $db1 === $db2 ? "Same instance" : "Different instances";
// Saída: Same instance

Elementos-chave:

  • Construtor privado — impede o uso direto de new
  • Propriedade estática — contém a instância única
  • Método estático — cria a instância na primeira chamada e a retorna nas chamadas subsequentes

Prevenindo clonagem e desserialização:

<?php
private function __clone() {}

public function __wakeup() {
    throw new Exception("Cannot unserialize singleton");
}

Experimente você mesmo

<?php

require_once 'Config.php';

// Ler entrada
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Obter a instância de Config e definir "app_name" como "MyApp"

// TODO: Obter uma segunda referência para Config usando getInstance() novamente

// TODO: Usar a segunda referência para definir a configuração usando $key e $value da entrada

// TODO: Verificar se o Singleton está funcionando:
// - Imprimir "Same instance: true" ou "Same instance: false" com base na comparação ===
// - Imprimir "Settings count: [count]" mostrando o total de configurações
// - Imprimir "App name: [value]" mostrando app_name recuperado 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