2010-01-20 5 views
10

저는 PHP 클래스와 객체를 사용하고 있습니다. 이 질문에서 필드와 메서드의 이름이 만들어져 있으므로 내가 말하는 것에 대한 아이디어를 얻을 수 있습니다.PHP의 레지스트리 또는 싱글 톤 패턴?

이것은 싱글 톤 및 레지스트리 디자인 패턴을 사용하는 것과 관련이 있습니다.

이제 데이터베이스 객체, 캐시 객체, 핵심 설정 객체, 세션 객체에 액세스해야한다고 가정 해 봅시다. 거의 모든 다른 클래스에서이 객체에 액세스해야합니다. 그래서 나는 레지스트리를 사용하여 4 개의 모든 객체를 하나의 레지스트리 클래스 객체에 저장합니다. 그러면 easiyl은 내 1 객체를 액세스해야하는 다른 객체로 전달할 수 있습니다. 지금까지는 그렇게 좋았지 만 네 개의 객체 모두를 필요로하지 않는 클래스가 있다면 어떻게 될까요? 다른 클래스의 일부에서 Database 객체 나 Session 객체에만 액세스해야합니까? perfromance를 위해서이 다른 객체 안에 싱글 톤을 사용하는 것이 가장 좋을까요? 아니면 이것들에서 내 레지스트리를 사용하는 것인가?

필자는 어떤 종류의 performnce gain (적은 메모리 사용량, CPU 사용량,로드 시간)이 있는지 PHP에서 객체가 어떻게 작동하는지 잘 모릅니다.

이렇게 경험이있는 사람이라면 누구나 사용할 수 있을지 알 수 있습니다. 제작 단계에 영향을 미치지 않고 이더넷 방식으로 갈 수있는 단계에 있습니다. 지금 할 수 있다면 최선의 방법을 사용하고 싶습니다. 단지 당신이 정말로 필요로하는 객체를로드에

+0

실제로 질문을 지금 막이 basicly 동일 발견 http://stackoverflow.com/questions/1967363/registry-or-singleton – JasonDavis

+0

당신은 PHP4 또는 PHP5를 사용하는 경우주의 받아 ... 객체 매우 다르게 작동하며, '정적'과 같은 PHP4 키워드는 지원되지 않습니다. 5 개를 사용하고있을 가능성이 있지만 관련 OOP에 참여하려면 확실해야합니다. –

답변

3

해당 응용 프로그램에 따라 다릅니다. 여전히 4 개 클래스 중 3 개가 필요하다면 4 번째 클래스가 필요 없기 때문에 레지스트리를 사용하는 것이 3 개 독립적으로 처리하는 것보다 더 적합 할 것입니다. 느슨하게 클래스를로드하는 것은 메모리 사용량을 줄이기위한 하나의 방법이지만 오브젝트를 작성할 때 레지스트리에 지시해야하며 싱글 톤 처리와 크게 다르지 않습니다. 또는 n - 매개 변수 생성자를 만들거나 배열을 사용하여 레지스트리를 생성하는 동안 인스턴스화 할 클래스를 지시 할 수 있습니다.

class Registry { 
    public $class1; 
    public $class2; 

    function __construct($uses) { 
     foreach($uses as $class) { 
      $this->{$class} = new {$class}(); 
     } 
    } 

} 

그런 다음 인스턴스를 생성 할 클래스를 지정하여 레지스트리를 인스턴스화하십시오.

$reg = new Registry(array('class1')); 

생성자가 모든 클래스를 기본적으로 인스턴스화하는 계정으로 0 매개 변수를 처리하도록하려는 경우가 있습니다.

+0

멋진 아이디어입니다. 감사합니다. 비록 1 개의 클래스가 1 ~ 2 개의 오브젝트만을 필요로한다고하더라도, 동일한 페이지에서 다른 클래스가 호출되어 4 개의 오브젝트가 모두 이미 삽입되어있을 가능성이 가장 높습니다. 나는 메모리 물건들이 어떻게 울려 퍼지는지 모르겠다. 그래서 그것은 이미 1 번로드되었을 것이다. 메모리가 RAM에 오브젝트를 한 번 이상 저장하는지 여부는 알 수 없습니다. – JasonDavis

+0

내 코드 예제에서는 클래스가 자신의 레지스트리 인스턴스에 고정되어 있다고 가정합니다. 이는 동일한 공통 레지스트리 객체를 사용하는 페이지 당 둘 이상의 클래스가있는 경우 초과 메모리를 많이 필요로합니다. 정적/전역 인스턴스를 사용하는 경우 구현이 내 예와 다를 수 있지만 여전히 수행 할 수 있습니다. 이는 또한 모든 클래스에 걸쳐 동일한 객체를 메모리에 공유하는 것을 의미합니다. 이는 훨씬 더 효율적입니다. 그런 식으로 작동하도록 예제를 만들려면 생성자를 사용하는 대신 Registry :: initInstances() 함수를 만듭니다. –

+0

좋아, 내가 생각했던 것, 우리가 같은 페이지에있는 것 같아. 일종의 dbemerlin의 메소드가 아래에있다. – JasonDavis

4

당신은 게으른 로딩을 구현할 수 있습니다

class Registry 
{ 
    private static $database = null; 

    private static function connectDatabase($key) 
    { 
     [... do connection stuff ...] 
    } 

    public static function getDatabase($key) 
    { 
     if (Registry::$database == null) 
     { 
      Registry::connectDatabase($key); 
     } 
     return Registry::$database; 
    } 
} 

데이터베이스 연결 매개 변수를 등록하는 코드는 독자에게 연습으로 남아 있습니다.

+3

이것은 단순한 싱글 톤이 아닙니까? – JasonDavis

+0

나는 싱글 톤 (singleton)이라고 할 수있는 것이 무엇인지 모르겠다. –

+0

이것은 순수한 싱글 톤 패턴이다. 실제로는 패턴이 아니고 안티 패턴이다. –

1

아마도 이것은 적절한 싱글 톤 레지스트리 패턴입니다. OFC, 당신은 다른 것들, SplFixedArray, ArrayAccess 인터페이스 등을 구현할 수 있습니다. 또한 누수가 없도록 내부 객체를 파괴하고 파괴하는 것도 나쁘지 않습니다.

class oRegistry{ 
    private static $instance = null; 

    private $storage = array(); 

    private function __construct(){} 

    private function __clone(){} 

    public static function getInstance(){ 
     if(self::$instance === null){ 
     self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function attach($name, $o) { 
     if(true === isset($this->storage[$name])) { 
      throw new Exception('The instance with name '.$name.' already exists in registry.'); 
     } 
     if(!empty($name)) { 
      $this->storage[ $name ] = $o; 
     } 
    } 

    public function detach($name){ 
     if(isset($this->storage[ $name ])) { 
      $this->storage[ $name ] = null; 
      unset($this->storage[ $name ]); 
     } 
    } 

    public function get($name){ 
     if(false === isset($this->storage[$name])) { 
      throw new Exception('Invalid instance requested'); 
     } 
     return $this->storage[ $name ]; 
    } 
} 

// usage example 
$storage = oRegistry::getInstance(); 
$obj = new stdClass; 
$obj2 = new stdClass; 
$obj->test1 = 'test'; 
$obj2->test2 = 't2'; 

$storage->attach('test1', $obj); 
$storage->attach('test2', $obj2); 

$got = $storage->get('test2'); 
var_dump($got); // object(stdClass)#3 (1) { ["test2"]=> string(2) "t2" } 

$storage->detach('test2'); 
$got = $storage->get('test2'); 
var_dump($got); // bool(false)