Menu
Coddy logo textTech

Wzorzec Singleton

Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 71 z 91.

Wzorzec Singleton to kreacyjny wzorzec projektowy, który zapewnia, że klasa ma tylko jedną instancję przez cały cykl życia aplikacji. Zapewnia również globalny punkt dostępu do tej instancji.

Ten wzorzec jest przydatny, gdy potrzebujesz dokładnie jednego obiektu do koordynowania działań w całym systemie, na przykład połączenia z bazą danych, menedżera konfiguracji lub rejestratora. Tworzenie wielu takich instancji marnowałoby zasoby lub powodowało niespójne działanie.

Oto jak zaimplementować Singletona w PHP:

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // Prywatny konstruktor uniemożliwia bezpośrednie tworzenie instancji
    }
    
    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";

Wynik:

Same instance

Wzorzec opiera się na trzech kluczowych elementach: prywatnym konstruktorze, który uniemożliwia bezpośrednie użycie new, właściwości statycznej, która przechowuje jedyną instancję, oraz metodzie statycznej, która tworzy instancję przy pierwszym wywołaniu i zwraca ją przy kolejnych wywołaniach.

Aby Singleton był naprawdę niezawodny, należy również zapobiec klonowaniu i deserializacji:

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

Wyzwanie

Łatwy

Zbudujmy menedżer konfiguracji z użyciem wzorca Singleton. W rzeczywistych aplikacjach zazwyczaj chcesz mieć jedno źródło prawdy dla ustawień konfiguracji: wiele obiektów konfiguracji mogłoby prowadzić do niespójnego działania systemu.

Rozmieścisz kod w dwóch plikach:

  • Config.php: Utwórz klasę Config, która implementuje wzorzec Singleton. Menedżer konfiguracji powinien:
    • Przechowywać ustawienia w prywatnej właściwości będącej tablicą
    • Mieć prywatny konstruktor, który inicjalizuje pustą tablicę ustawień
    • Udostępniać statyczną metodę getInstance(), która zwraca jedyną instancję
    • Uniemożliwiać klonowanie, ustawiając metodę __clone() jako prywatną
    • Zawierać metodę set(string $key, string $value): void do zapisywania ustawienia
    • Zawierać metodę get(string $key): ?string, która zwraca wartość dla klucza lub null, jeśli klucz nie istnieje
    • Zawierać metodę getAll(): array, która zwraca wszystkie ustawienia
  • main.php: Dołącz plik Config. Otrzymasz dwa dane wejściowe: klucz i wartość.

    Pobierz instancję Config i ustaw domyślne ustawienie z kluczem "app_name" i wartością "MyApp".

    Pobierz drugie odwołanie do instancji Config (ponownie używając getInstance()) i użyj go do ustawienia kolejnego ustawienia przy użyciu klucza i wartości z danych wejściowych.

    Na koniec sprawdź, czy Singleton działa poprawnie:

    • Wypisz "Same instance: true" lub "Same instance: false" w zależności od tego, czy oba odwołania wskazują ten sam obiekt (użyj === do porównania)
    • Wypisz "Settings count: [count]", pokazując całkowitą liczbę zapisanych ustawień (użyj count() na wyniku getAll())
    • Wypisz "App name: [value]", pokazując ustawienie app_name pobrane przez drugie odwołanie

To wyzwanie pokazuje główną zaletę wzorca Singleton: niezależnie od tego, ile razy wywołasz getInstance(), zawsze otrzymasz ten sam obiekt, dzięki czemu wszystkie części aplikacji współdzielą ten sam stan konfiguracji.

Spróbuj swoich sił

<?php

require_once 'Config.php';

// Odczytaj dane wejściowe
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Pobierz instancję Config i ustaw "app_name" na "MyApp"

// TODO: Uzyskaj drugie odwołanie do Config, ponownie używając getInstance()

// TODO: Użyj drugiego odwołania, aby ustawić wartość ustawienia na podstawie $key i $value z danych wejściowych

// TODO: Sprawdź, czy Singleton działa:
// - Wypisz "Same instance: true" lub "Same instance: false" na podstawie porównania ===
// - Wypisz "Settings count: [count]", pokazując łączną liczbę ustawień
// - Wypisz "App name: [value]", pokazując wartość app_name pobraną przez drugie odwołanie

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online