Menu
Coddy logo textTech

Pattern Singleton

Fa parte della sezione Programmazione orientata agli oggetti del percorso PHP di Coddy. Lezione 71 di 91.

Il Singleton Pattern è un pattern di progettazione creazionale che garantisce che una classe abbia una sola istanza per tutto il ciclo di vita della tua applicazione. Fornisce anche un punto di accesso globale a tale istanza.

Questo schema è utile quando hai bisogno di esattamente un oggetto per coordinare le azioni nell’intero sistema, come una connessione al database, un gestore della configurazione o un logger. Creare più istanze di questi oggetti sprecherebbe risorse o causerebbe comportamenti incoerenti.

Ecco come implementare un Singleton in PHP:

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // Il costruttore privato impedisce l'istanziazione diretta
    }
    
    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";

Output:

Same instance

Lo schema si basa su tre elementi chiave: un costruttore privato che impedisce di usare direttamente new, una proprietà statica che contiene l’unica istanza e un metodo statico che crea l’istanza alla prima chiamata e la restituisce alle chiamate successive.

Per rendere il Singleton davvero a prova di errore, dovresti anche impedire la clonazione e la deserializzazione:

<?php
private function __clone() {}
public function __wakeup() {
    throw new Exception("Cannot unserialize singleton");
}
challenge icon

Sfida

Facile

Creiamo un gestore della configurazione usando il Pattern Singleton. Nelle applicazioni reali, in genere vuoi un'unica fonte attendibile per le impostazioni di configurazione: avere più oggetti di configurazione potrebbe causare comportamenti incoerenti nel sistema.

Organizzerai il codice in due file:

  • Config.php: crea una classe Config che implementa il Pattern Singleton. Il gestore della configurazione dovrebbe:
    • Memorizzare le impostazioni in una proprietà array privata
    • Avere un costruttore privato che inizializza l'array delle impostazioni come vuoto
    • Fornire un metodo statico getInstance() che restituisce l'unica istanza
    • Impedire la clonazione rendendo privato __clone()
    • Includere un metodo set(string $key, string $value): void per memorizzare un'impostazione
    • Includere un metodo get(string $key): ?string che restituisce il valore di una chiave, oppure null se la chiave non esiste
    • Includere un metodo getAll(): array che restituisce tutte le impostazioni
  • main.php: includi il file Config. Riceverai due input: una chiave e un valore.

    Ottieni l'istanza di Config e imposta un'impostazione predefinita con la chiave "app_name" e il valore "MyApp".

    Ottieni un secondo riferimento all'istanza di Config (usando di nuovo getInstance()) e usalo per impostare un'altra impostazione usando la chiave e il valore degli input.

    Infine, verifica che il Singleton funzioni correttamente:

    • Stampa "Same instance: true" oppure "Same instance: false" a seconda che entrambi i riferimenti puntino allo stesso oggetto (usa === per confrontarli)
    • Stampa "Settings count: [count]" mostrando il numero totale di impostazioni memorizzate (usa count() sul risultato di getAll())
    • Stampa "App name: [value]" mostrando l'impostazione app_name recuperata tramite il secondo riferimento

Questa sfida dimostra il vantaggio fondamentale del Pattern Singleton: non importa quante volte chiami getInstance(), ottieni sempre lo stesso oggetto, assicurando che tutte le parti della tua applicazione condividano lo stesso stato di configurazione.

Provalo tu

<?php

require_once 'Config.php';

// Leggi l'input
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Ottieni l'istanza di Config e imposta "app_name" su "MyApp"

// TODO: Ottieni un secondo riferimento a Config usando di nuovo getInstance()

// TODO: Usa il secondo riferimento per impostare la configurazione con $key e $value ricevuti in input

// TODO: Verifica che Singleton funzioni:
// - Stampa "Same instance: true" o "Same instance: false" in base al confronto ===
// - Stampa "Settings count: [count]" mostrando il numero totale di impostazioni
// - Stampa "App name: [value]" mostrando app_name recuperato tramite il secondo riferimento

?>
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore PHP online