2010-04-06 3 views
5

싱글 톤 클래스 확장 :내가 이런 싱글 톤 클래스의 인스턴스를 생성하는 데 사용

$Singleton = SingletonClassName::GetInstance(); 

및 비 싱글 톤 클래스 : 내가 생각

$NonSingleton = new NonSingletonClassName; 

우리는 우리가를 만드는 방법을 구분하지합니다 이것이 싱글 톤인지 여부에 관계없이 클래스의 인스턴스. 만약 내가 다른 수업의 인식을 들여다 보면, 나는 우리가 싱글 톤 수업이 필요한지 아닌지 상관하지 않는다. 그래서, 나는 여전히 PHP가 싱글 톤 클래스를 다루는 방법에 만족하지 않는다. 나는 항상 쓰기를 원한다고 생각한다 :

이 문제에 대한 해결책이 있습니까?

+1

이 질문은 문제가되지 않습니다. 패턴을 완성하는 방법을 좋아하지 않는다고 불평하는 것입니다. -1 –

+1

이것은 매우 정당한 질문입니다. +1은 -1이 아니기 때문에 +1 : P – Leo

+2

PHP를 사용하지 마십시오 ?? – Kevin

답변

2

나는 그것을 권하고 싶지 않다 :-) 새로운라는 이유 이잖아 클래스의 새로운 인스턴스를 생성 (사람들은 새로운 완전히 새로운 개체를 의미한다고 생각). 그러나 그때 나는 싱글 톤의 사용을 다시 생각하지 않을 것이다.

이 코드의 기본 개념은 싱글 톤 주위에 래퍼가 있다는 것입니다. 랩퍼를 통해 액세스되는 모든 함수와 변수는 실제로 싱글 톤에 영향을줍니다. 아래의 코드는 마술 방법과 SPL 인터페이스를 많이 구현하지 않습니다하지만 그들은

코드

/** 
* Superclass for a wrapper around a singleton implementation 
* 
* This class provides all the required functionality and avoids having to copy and 
* paste code for multiple singletons. 
*/ 
class SingletonWrapper{ 
    private $_instance; 
    /** 
    * Ensures only derived classes can be constructed 
    * 
    * @param string $c The name of the singleton implementation class 
    */ 
    protected function __construct($c){ 
     $this->_instance = &call_user_func(array($c, 'getInstance')); 
    } 
    public function __call($name, $args){ 
     call_user_func_array(array($this->_instance, $name), $args); 
    } 
    public function __get($name){ 
     return $this->_instance->{$name}; 
    } 
    public function __set($name, $value){ 
     $this->_instance->{$name} = $value; 
    } 
} 

/** 
* A test singleton implementation. This shouldn't be constructed and getInstance shouldn't 
* be used except by the MySingleton wrapper class. 
*/ 
class MySingletonImpl{ 
    private static $instance = null; 
    public function &getInstance(){ 
     if (self::$instance === null){ 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    //test functions 
    public $foo = 1; 
    public function bar(){ 
     static $var = 1; 
     echo $var++; 
    } 
} 

/** 
* A wrapper around the MySingletonImpl class 
*/ 
class MySingleton extends SingletonWrapper{ 
    public function __construct(){ 
     parent::__construct('MySingletonImpl'); 
    } 
} 

$s1 = new MySingleton(); 
echo $s1->foo; //1 
$s1->foo = 2; 

$s2 = new MySingleton(); 
echo $s2->foo; //2 

$s1->bar(); //1 
$s2->bar(); //2 
를 필요한 경우에 추가 할 수는 완벽하지 않습니다
+0

와우, 멋지다. 대단히 감사합니다! – cakyus

3

이 더 나은 다른 방법으로 주위가 수 - 비 - 싱글을위한 factory-method을 제공하고, 사용하여 인스턴스를 얻을 :

$NonSingleton = NonSingletonClassName::createInstance(); 

이 그것을 적용 (Effective Java에서) 자바에 대한 권장 모범 사례가 있지만, 대부분의 객체 지향 언어에 적용됩니다.

1

일반 클래스 인스턴스와 같은 방식으로 싱글 톤을 만들 수 없습니다. new은 항상 새 인스턴스를 반환하므로 public이 아닌 생성자가 있어야하므로 클래스 내에서이를 호출하는 다른 방법이 있어야합니다.

모든 클래스에 대한 팩토리 메소드가있을 수 있습니다 (예 : 항상 getInstance()과 같은 대답을하는 것이 좋습니다. 또 다른 옵션은 무엇을 반환할지 여부를 알고있는 Service LocatorDependency Injection Framework을 사용하는 것입니다.

1

키워드에 따라 new은 원하는 것이 모두 부적절하다는 것을 의미합니다. new는 이해하기 코드를 훨씬 어렵게 만들 것대로

+0

하하 .. 당신은 절대적으로 맞습니다 :-) – cakyus