2011-01-11 11 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(ある変数);'? –

+1

コンストラクタを使用して、ある時点ですでに作成されているものを作成することは意味がありません。たとえば、現在のプロジェクトでは、Profile :: get()を使用して、(ある時点で)既に「構築済み」のプロファイルを読み込みます。おそらく、私はコンストラクタを誤用しているか、またはこれをオーバーロードの答えとして使用しています。 – daniel

答えて

68

あなたはそれをやっているといいです。あなたの人生をより簡単にすることができる他にもいくつかのことがあります。

  1. クラス名をハードコードしないでください。 5.3以上の場合は、キーワードstaticを使用してください。

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

    は、その後、あなたが何かを上書きすることなく、任意の拡張クラスでそれを使用することができます:あなたは、クラスを拡張する場合はその方法は、新しい機能は、同様にその1をインスタンス化することができます。

  2. $varは、構築後に設定するのではなく、コンストラクタで渡す必要がある場合を示します。オブジェクトがそれに依存している場合は、それを要求する必要があります。

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

    このようにして、変数を設定せずにオブジェクトをインスタンス化することはできません。

  3. 静的メソッドを使用してクラスのインスタンス化を強制します。そこに何かする必要がある場合は、コンストラクタをprotectedまたはprivateのいずれかにします。そうすれば、誰かが静的メソッドをバイパスすることはできません。

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

私はそれが役に立てば幸い...

編集:上記のコメントに基づいて、Singleton Design Patternを実装しようとしているように聞こえます。なぜそれが素晴らしいアイデアではないか、悪いことが起こるかもしれないということについて、たくさんの情報があります。それにも用途があります。

しかし、正確にやっていることに応じて、あなたにとって役に立つかもしれない他のパターンがいくつかあります。

  • 同じ手順で異なるオブジェクトを作成しようとしている場合はFactory Methodを使用できます。
  • すべてのオブジェクトが同じように開始してからカスタマイズされている場合は、Prototype Patternを使用できます。
  • オブジェクトを作成するのに特にコストがかかる場合は、Object Poolを使用できます。

ただし、考慮すべき点は、PHPオブジェクトはかなり軽量であることです。そのオーバーヘッドのためだけに新しいオブジェクトを作成しないようにしないでください。データベースクエリやファイルシステムアクセスのような重い作業を何度もやることは避けてください。しかしnew Foo()を呼び出すことについて心配しないでください。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
関連する問題