Menu
Coddy logo textTech

싱글턴 패턴

Coddy PHP 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 91개 중 71번째.

Singleton Pattern은 애플리케이션의 전체 수명 주기 동안 클래스에 하나의 인스턴스만 존재하도록 보장하는 생성 디자인 패턴입니다. 또한 해당 인스턴스에 대한 전역 접근 지점을 제공합니다.

이 패턴은 데이터베이스 연결, 구성 관리자 또는 로거와 같이 시스템 전반의 작업을 조정하기 위해 정확히 하나의 객체가 필요할 때 유용합니다. 이러한 객체의 인스턴스를 여러 개 생성하면 리소스가 낭비되거나 일관되지 않은 동작이 발생할 수 있습니다.

PHP에서 Singleton을 구현하는 방법은 다음과 같습니다:

<?php
class Database {
    private static ?Database $instance = null;
    
    private function __construct() {
        // 비공개 생성자는 직접 인스턴스화를 방지합니다
    }
    
    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";

출력:

Same instance

이 패턴은 세 가지 핵심 요소에 의존합니다. new를 직접 사용하는 것을 prevents하는 private constructor, 단일 instance를 보유하는 정적 property, 그리고 첫 번째 호출에서 instance를 생성하고 이후 호출에서 이를 returns하는 정적 method입니다.

Singleton을 진정으로 빈틈없이 만들려면 복제와 역직렬화도 prevent해야 합니다:

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

챌린지

쉬움

Singleton Pattern을 사용하여 구성 관리자를 만들어 보겠습니다. 실제 애플리케이션에서는 일반적으로 구성 설정을 위한 단일 진실 공급원을 원합니다. 여러 구성 객체가 있으면 시스템 전체에서 일관되지 않은 동작이 발생할 수 있습니다.

코드를 두 파일로 구성합니다.

  • Config.php: Singleton Pattern을 구현하는 Config class를 Create합니다. 구성 관리자는 다음을 수행해야 합니다.
    • 설정을 private array property에 저장
    • settings array를 empty로 initializes하는 private constructor 보유
    • 단일 instance를 returns하는 static getInstance() method 제공
    • __clone()을 private으로 만들어 cloning을 prevent
    • 설정을 저장하는 set(string $key, string $value): void method 포함
    • key에 대한 값을 returns하고, key가 존재하지 않으면 null을 returns하는 get(string $key): ?string method 포함
    • 모든 설정을 returns하는 getAll(): array method 포함
  • main.php: Config 파일을 포함합니다. 두 개의 입력, 즉 key와 value를 받습니다.

    Config instance를 가져온 다음, key가 "app_name"이고 value가 "MyApp"인 기본 설정을 지정합니다.

    Config instance에 대한 두 번째 reference를 가져오고(getInstance()를 다시 사용), 이를 사용하여 입력에서 받은 key와 value로 다른 설정을 지정합니다.

    마지막으로 Singleton이 올바르게 작동하는지 확인합니다.

    • 두 reference가 동일한 object를 가리키는지에 따라 "Same instance: true" 또는 "Same instance: false"를 Print합니다(===를 사용하여 비교).
    • 저장된 설정의 총 개수를 보여 주는 "Settings count: [count]"를 Print합니다(getAll()의 결과에 count()를 사용).
    • 두 번째 reference를 통해 retrieved한 app_name 설정을 보여 주는 "App name: [value]"를 Print합니다.

이 challenge는 Singleton Pattern의 핵심 이점을 보여 줍니다. getInstance()를 몇 번 호출하더라도 항상 동일한 object를 얻으므로 애플리케이션의 모든 부분이 동일한 구성 상태를 공유할 수 있습니다.

직접 해보기

<?php

require_once 'Config.php';

// 입력 읽기
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));

// TODO: Config 인스턴스를 가져와 "app_name"을 "MyApp"으로 설정

// TODO: getInstance()를 다시 사용하여 Config에 대한 두 번째 참조 가져오기

// TODO: 두 번째 참조를 사용하여 입력의 $key와 $value로 설정 지정

// TODO: 싱글톤이 작동하는지 확인:
// - Print "Same instance: true" or "Same instance: false" based on === comparison
// - Print "Settings count: [count]" showing total settings
// - 두 번째 참조를 통해 가져온 app_name을 표시하는 "App name: [value]" 출력

?>
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 PHP 컴파일러