2010-11-30 8 views
1

標準に関する質問です。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()メソッドを使用し続けます。私はそれを間違っているのですか?


EDIT:私の質問ビットの絞り込み。シングルトンのためにgetInstance()を使用することを除いて、私のコンストラクタはcreate()メソッドでラップされています。真のコンストラクタから例外をスローするか、またはcreate()からfalseを返す必要がありますか?

答えて

1

シングルトンは一般的に「不良」とみなされます。トピックに関する炎戦についてはthis section hereを参照してください。あなたは罰金しているように、オブジェクトを作成するファクトリメソッドまたはファクトリクラスを使用すると、一般的に存在し、良いと考えられている、と述べた:)

私は個人的に(symfonyのを使用せずに、任意のプロジェクトにインストールすることができsymfony dependency injectionコンポーネントを使用

依存関係注入を簡素化し、シングルトンを避けることが適切であると思われる場合に使用します。

私はまだシングルトンを使用しています。ロガーや工場のオブジェクトは、当然のことながら、私にとっては独身のように見えるので、私はそのようにしています。グローバルの機能(例:工場)は問題ありませんが、グローバルの状態はが悪いと考えています。

例外をスローするかどうか、またはcreate()コールからfalseを返すかどうかに関する修正された質問に関しては、作成されたオブジェクトがなくてもアプリケーションが正常に続行できるかどうかによって異なります。たとえば、ページを作成するために必要なデータベース接続を作成する場合は、例外をスローします。あまり本質的でないことをしている場合は、falseを返信してメリー・ウェイでやり続けてください:)

+2

シングルトンパターンが悪くないことは確かです。それを過度に使うことは悪いです(何が悪いことも悪いので)。 :) – egis

+0

節度のすべてのもの、私は思います:) –

+0

ありがとうございます**エルYobo **;私はあなたの提案を見てみましょう:) – Dan

0

getInstance() Zend Frameworkのすべての場所で使用されています。これはコードの標準と慣習のための私のgotoです。

については、new Blah()の場合は、そのクラスのメソッドを呼び出すように、魔法の__constructメソッドを使用してください。

+0

私は '__construct'をprivate(または継承を扱うときは保護)に設定し、' create() 'から' new self($ args); 'を返します – Dan

+0

@ Tomcatは、あなたのオブジェクトの2つのインスタンスを作成しませんか? $ 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を無視してください。 –

関連する問題