2010-11-30 4 views
1

표준에 관한 질문.PHP : 인스턴스 생성을 막는 클래스 생성자의 표준

PHP 세션 관리를위한 래퍼 클래스를 만들었습니다. PHP 세션 관리에 액세스하는 특정 내부 모듈을 기반으로 세션 데이터를 자동으로 구성하는 데 도움이됩니다. 주어진 시간에 단 하나의 세션 만 있기 때문에 getInstance() 메소드를 사용하여 싱글 톤으로 설계되었습니다. 또한 이것은 (아마도 제한적 임에도 불구하고) session_start()이 실패했을 때 세션 객체의 인스턴스화를 막을 수 있기 때문에 이것은 나에게 도움이되었습니다. 예를 들면 :

public static function getInstance(){ 
     if(!self::$_instance || !session_id()){ 
      if(session_start()){ 
       self::$_instance = new self(session_id()); 
      }else{ 
       return; 
      } 

     } 
     return self::$_instance; 
    } 

내 질문은; 게이트웨이 getInstance() 메서드를 사용하는 것이 몇 가지 이유에서 자연스럽게 작동하지만 객체가 외부 조건에 의존 할 경우 객체 생성을 제어하는 ​​클래스에 public static getInstance() 또는 create() 메서드를 구현하는 것이 일반적/우수 사례입니까?

싱글 톤의 경우 getInstance()을 제공하고 다중 인스턴스 개체의 경우 create()을 제공하는 규칙을 고수하고 있습니다.

TL : 모든 개체 인스턴스화를 제어하기 위해 getInstance()create() 메서드를 계속 사용합니다. 내가 잘못하고 있니?


편집 : 내 질문에 조금 정련; 싱글 톤을 위해서 getInstance()을 사용하는 것 외에, create() 메쏘드로 래핑하는 것은 덜 목적이 있고 더 나쁜 컨벤션을 향하여 더 기울고 있는가? true 생성자에서 예외를 던지거나 create()에서 false를 계속 반환해야합니까?

답변

1

싱글 톤은 일반적으로 "나쁜"것으로 간주됩니다. 주제에 대한 화염 전쟁은 this section here을 참조하십시오.

은 잘 거기 :)

개인적 심포니를 사용하지 않고 모든 프로젝트에 설치할 수 있습니다합니다 (symfony dependency injection 구성 요소를 사용하여 일반적으로 좋은 생각 있도록되어 객체를 작성하는 팩토리 메소드 또는 공장 클래스를 사용했다 그 프레임 워크)를 사용하여 종속성 삽입을 단순화하고 적절하다고 판단되는 곳에서 싱글 톤을 피할 수 있습니다.

나는 여전히 나에게 의미가있는 몇 가지 싱글 톤을 사용한다. 로거 및 공장 객체는 자연스럽게 나에게는 독창적 인 것처럼 보입니다. 그래서 나는 그렇게합니다. 글로벌 기능이 (예 : 공장)이지만, 글로벌 상태는이 좋지 않다고 생각합니다.

예외를 던질 지 또는 create() 호출에서 false를 반환할지 여부에 대한 수정 된 질문과 관련하여; 생성 된 객체가 없으면 애플리케이션을 성공적으로 계속 사용할 수 있는지 여부에 따라 다릅니다. 예를 들어, 페이지를 작성하는 데 필요한 데이터베이스 연결을 작성한 경우 예외를 발생시킵니다. 만약 당신이 덜 중요한 일을한다면, false를 반환하고 명랑한 방법으로 계속하십시오 :

+2

싱글 톤 패턴이 나쁘지는 않습니다. 그것을 과용하는 것은 나쁘다. :) – egis

+0

적당히 모든 것, 나는 생각한다 : –

+0

감사합니다 ** El Yobo **; 나는 너의 제안을 보게 될 것이다 :) – Dan

0

getInstance() Zend Framework의 모든 곳에서 사용됩니다. 이것은 코드의 표준 및 규칙에 대한 나의 고토입니다.

create()와 마찬가지로 마법 __construct 메서드를 사용하면 new Blah()을 호출 할 때 해당 클래스에 대해 __construct 메서드가 호출됩니다.

+0

'__construct'를 private (또는 상속을 처리 할 때 보호)로 설정하고'create()'에서'new ($ args);'를 리턴한다. – Dan

+0

so @ Tomcat, 그 두 개체의 인스턴스를 만들까요? $ object1 = 새로운 Blah(). $ object2 = $ object1-> create(); 당신의 방법은 어떤 이점을 제공합니까? –

+0

인스턴스리스 메소드 체이닝 ('Class :: create() -> method() -> method();'), none을 허용하는 것을 제외하고는. 'new' 키워드와 인스턴스 검색 메소드를 같은 범위에서 섞는 것에 대해 이상한 숙제가 있습니다. – Dan

0

사용자가 __construct 메소드를 작성한 다음 create 메소드를 사용해야합니다. __construct은 자체적으로 호출되므로 생성자에서 초기화 및 기타 작업을 수행 할 수 있습니다. 또 다른 이점은 create() 메서드를 호출하는 것을 잊을 수 있으며 개체의 상태가 일관되지 않을 수 있다는 것입니다.

+0

나는 잊지 않는다 :) 또한, 나는 종종 이것을한다. 'if ($ obj = Class :: create()) {', 따라서 인스턴스화 실패의 조건을 제공하지만, 예외를 더 남겨 둘 수 있을까요? – Dan

+0

팩토리 메서드의 포인트는 객체를 인스턴스화하는 일관된 방법을 제공하고 필요한 경우 다른 객체로 쉽게 대체 할 수 있도록하는 것입니다. $ foo = new Bar()를 사용하는 경우 모든 Bar 객체를 Blarg로 변경하려면 모든 새 Bar() 문을 바꿔야합니다. 팩토리를 사용하는 경우 팩토리 만 대체합니다. 즉, 당신이하고있는 일은 이미 훌륭합니다. Shashwat을 무시하십시오. –

관련 문제