오늘은 싱글턴 패턴에 대해 이야기해보겠습니다.
저는 예전에 Java 개발을 하다가 싱글톤 모드를 사용할 때 먼저 배고픈 중국식 스타일을 사용할까 생각하다가 PHP에 이런 기능이 있다는 것을 알게 되었습니다. 왜냐하면 PHP는 클래스 정의 중에 클래스의 멤버 변수에 비기본 유형 값 할당을 지원하지 않기 때문입니다. 표현식, 새로운 연산 등 따라서 배고픈 중국 스타일은 작동하지 않습니다. 대신, 나는 이 싱글톤 모드의 원자성을 보장하고 싶었고, JAVA처럼 PHP에는 스레드 안전 문제가 없다는 것을 발견했습니다. 안녕하세요, PHP가 좋다고 생각하시나요? 좋습니다. 그러면 PHP의 게으른 싱글톤 모드를 시도해 보겠습니다.
먼저 이야기하지 말고 먼저 싱글톤 모드 코드의 첫 번째 버전을 소개하겠습니다.
// 定义私有静态变量.此种方式为:懒汉式单例(PHP中只有这种方式) private static $instance = null; // 私有化构成方法 private function __construct(){ } // 提供获取实例的公共方法 public static function getInstance(){ if(!(self::$instance instanceof self)){ self::$instance = new self(); } return self::$instance; } // 私有__clone方法,禁止复制对象 private function __clone(){ }좋아요, 이 코드는 주석과 서식이 포함되어 완벽해 보이므로 문제가 없습니다. 그런데 사용하다가 문제를 발견했습니다.
내 클래스 A가 싱글톤 모드에 있고, 내 클래스 B가 클래스 A에서 상속받고, 다음 메서드를 호출합니다.
$a = A::getInstance(); $b = B::getInstance(); var_dump($a === $b);출력 결과는 다음과 같습니다. bool(true)
$b = B::getInstance();을 통해 얻은 객체가 여전히 클래스 A의 객체임을 의미할 수 있습니다. 그러면 무슨 일이 일어나고 있나요?
self의 참조는 클래스가 정의될 때 결정됩니다. 즉, A가 B를 상속하더라도 해당 자체 참조는 여전히 A를 가리킵니다. 이 문제를 해결하기 위해 PHP 5.3에서는 후기 정적 바인딩 기능이 도입되었습니다. 간단히 말해서 정적 메서드나 변수는 static 키워드를 통해 액세스됩니다. self와 달리 정적 참조는 런타임에 결정됩니다. 따라서 싱글톤 모드를 재사용할 수 있도록 코드를 다시 작성하기만 하면 됩니다.
class C { protected static $_instance = null; protected function __construct(){ } protected function __clone(){ } public function getInstance(){ if (static::$_instance === null) { static::$_instance = new static; } return static::$_instance; } } class D extends C{ protected static $_instance = null; } $c = C::getInstance(); $d = D::getInstance(); var_dump($c === $d);이때 출력은 다음과 같습니다. bool(false)
그러면 이 싱글톤 모드를 상속하는 한 이를 달성할 수 있으며 해당 하위 클래스도 싱글톤 모드가 됩니다. 이렇게 하면 싱글톤 모드가 필요할 때마다 너무 많은 반복 코드를 작성하지 않고도 완벽한 재사용이 가능합니다. 위 메소드는 PHP 5.3에서만 사용할 수 있다는 점에 유의하세요. 이전 버전의 PHP에서는 각 싱글톤 클래스마다 getInstance() 메소드를 작성하는 것이 좋습니다.
위에서는 API 개발의 세 번째 부분인 PHP 디자인 패턴을 소개합니다. 내용의 측면을 포함한 완벽한 싱글톤 패턴이 PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.