2011-01-11 7 views
26

제목에서 알 수 있듯이 같은 클래스의 정적 메서드 내에서 클래스의 인스턴스를 만들고 싶습니다. 나는 지금까지 이렇게 할 수 있다는 것을 알아 냈습니다.정적 메서드 내에서 클래스 인스턴스 만들기

class Foo{ 

public $val; 

public static function bar($val){ 
    $inst = new Foo; 
    $inst->val = $val; 
    return $inst; 
} 

} 

따라서 이렇게 할 수 있습니다.

$obj = Foo::bar("some variable"); 

위대한 분입니다.

그럼 이제 질문입니다. 이 작업을 쉽게 수행 할 수있는 방법이 있습니까? 또는 동일한 결과를 얻는 데 필요한 단축키가 있습니까? 이런 방식으로 인스턴스를 생성하는 데있어 장점이나 단점이 있습니까?

감사합니다.

+2

이런 식으로 일을하는 이유는 무엇입니까? 왜'$ obj = new Foo ("some variable")를 사용하지 않을까요? –

+1

이미 어느 시점에서 만들어진 생성자로 무언가를 만드는 것은 나에게 의미가 없다. 예를 들어, 현재 프로젝트에서 Profile :: get()을 사용하여 (어느 시점에서) 이미 "생성 된"프로파일을로드합니다. 아마도 나는 생성자를 오용하거나 오버로드에 대한 대답으로 이것을 사용하고 있습니다. – daniel

답변

68

당신이하고있는 길은 괜찮습니다. 당신이 할 수있는 일을 더 쉽게 할 수있는 몇 가지 다른 것들이 있습니다.

  1. 클래스 이름을 하드 코딩하지 마십시오. 5.3 이상인 경우 static 키워드를 사용하십시오.

    public static function bar($var) { 
        $obj = new static(); 
        $obj->var = $var; 
        return $obj; 
    } 
    

    그런 다음 당신은 아무것도를 오버라이드 (override) 할 필요없이 확장 클래스에서 사용할 수 있습니다 : 당신이 클래스를 확장하는 경우 그 방법은, 새로운 기능은 물론 하나의 인스턴스를 할 수 있습니다.

  2. $var이 생성 후 설정되지 않고 생성자를 통해 전달되어야하는 경우를 찾습니다. 객체가 종속되어있는 경우 객체를 필요로합니다.

    public function __construct($var) { 
        $this->var = $var; 
    } 
    

    그런 식으로 변수를 설정하지 않고 개체를 인스턴스화 할 수 없습니다.

  3. 정적 메서드를 통해 클래스의 인스턴스화를 적용합니다. 거기에서 수행해야 할 작업을 수행하는 경우 생성자를 보호 또는 비공개로 설정하십시오. 그렇게하면 누군가 정적 메서드를 무시할 수 없습니다.

    protected function __construct() {} 
    private function __construct() {} 
    

나는 희망이 도움이 ...

편집 : 위의 의견을 바탕으로 Singleton Design Pattern을 구현하려는 것 같습니다. 왜 그것이 좋은 생각이 아니며 그것이 할 수있는 나쁜 일들에 대한 많은 정보가 있습니다. 그것은 또한 용도가 있습니다.

하지만 정확히 무엇을하는지에 따라 사용할 수있는 몇 가지 패턴이 있습니다.

  • 동일한 단계를 사용하여 다른 개체를 만들려는 경우 Factory Method을 사용할 수 있습니다.
  • 모든 개체가 동일하게 시작되어 사용자 지정된 경우 Prototype Pattern을 사용할 수 있습니다.
  • 개체를 만들 때 특히 비싸면 Object Pool을 사용할 수 있습니다.

하지만 한 가지 고려해야 할 점은 PHP 객체가 꽤 가볍습니다. 그 오버 헤드에 대해서만 새로운 객체를 만드는 것을 피하려고하지 마십시오. 데이터베이스 쿼리 또는 파일 시스템 액세스와 같은 무거운 일을 여러 번 수행하지 마십시오. 그러나 foo의 생성자가 특히 무겁다면 new Foo()을 호출하는 것에 대해 걱정하지 마십시오.

0

개체를 만드는 경우 매우 유용하지 않습니다. 당신은 생성자를 호출 할 수 있습니다. 하지만 좀 더 복잡한 작업 (예 : 일종의 싱글 톤 패턴으로 시작했지만이 예에서 모든 세부 정보를 포함하지 않은 경우)을 수행하는 경우 다음을 수행하십시오.

이 같은 기본 방법으로 만든 개체 방지하려면 :

$obj = new Foo("Some Variable"); 

을 당신은 개인 생성자를 추가 할 수 있습니다

class Foo{ 

public $val; 

private __construct(){} 

public static function bar($val){ 
    $inst = new Foo; 
    $inst->val = $val; 
    return $inst; 
} 
} 

이제 정적 클래스를 사용하는 사람들을 적용합니다. 함수에서 val을 설정해야 할 필요가 없어 졌으므로 개인 생성자에 value-parameter를 추가 할 수도 있지만 (사용자가 원하는 것처럼, 일종의 싱글 톤 패턴을 확인하는 등) 다른 작업을 수행 할 수도 있습니다. '바 (bar)'기능

3

이것은 간단한 팩토리 메서드 패턴처럼 보입니다.

당신은 좋은 이점이 있습니다. 나중에 다른 구현을 사용하기를 원한다고 가정 해보십시오. 팩토리를 사용하면 생성자 메서드를 변경하여 복잡한 시스템의 여러 위치에서 생성 된 모든 객체를 변경할 수 있습니다. 외부 클래스를 사용하면 (아래 첫 번째 링크와 마찬가지로)이 작업이 더 쉬워집니다.

지금까지와 마찬가지로이 클래스를 서브 클래스 화하고이 메소드를 재정 의하여 더 복잡한 객체를 만들 수 있습니다. 나는 이것이 당신이 여기에서 성취하기를 원하는 것이라고 생각하지 않습니다.

어쨌든 테스트 기반 개발, 추상화 및 기타 여러 가지 유용한 기능을 사용하는 것이 좋습니다.

링크 :

  1. Php patterns
  2. Factory method pattern on wikipedia
관련 문제