私はこのようなコードを見たことがありません:
public static function getInstance()
{
if ( ! isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
と同じnew className()
ですか?
編集
クラスが継承されている場合、どのクラスを指しますか?
self
それが書かれているクラスを指します。
したがって、getInstanceメソッドがクラス名に含まれているMyClass
場合、次の行になります。
self::$_instance = new self();
と同じことをします:
self::$_instance = new MyClass();
編集:コメントの後、もう少し情報。
相互に拡張する2つのクラスがある場合、2つの状況があります。
getInstance
子クラスで定義されていますgetInstance
親クラスで定義されています最初の状況は次のようになります(この例では、不要なコードをすべて削除しました。シングルトンの動作を取得するには、コードを追加し直す必要があります)*:
class MyParentClass {
}
class MyChildClass extends MyParentClass {
public static function getInstance() {
return new self();
}
}
$a = MyChildClass::getInstance();
var_dump($a);
ここでは、次のようになります。
object(MyChildClass)#1 (0) { }
つまり、つまり、それが記述されているクラスをself
意味します。MyChildClass
class MyParentClass {
public static function getInstance() {
return new self();
}
}
class MyChildClass extends MyParentClass {
}
$a = MyChildClass::getInstance();
var_dump($a);
そして、あなたはこの種の出力を得るでしょう:
object(MyParentClass)#1 (0) { }
つまり、self
つまりMyParentClass
、ここでも、それが記述されているクラスを意味します。
static
で使用した場所で正確に使用できるようになりました。self
class MyParentClass {
public static function getInstance() {
return new static();
}
}
class MyChildClass extends MyParentClass {
}
$a = MyChildClass::getInstance();
var_dump($a);
しかし、のstatic
代わりにself
、次のようになります。
object(MyChildClass)#1 (0) { }
つまり、ある種は、それが書かれているクラスではなく、使用されている(私たちが使用した)クラスをstatic
指しているということです。MyChildClass::getInstance()
もちろん、self
既存のアプリケーションを壊さないように、の動作は変更されていません。PHP5.3は、static
キーワードをリサイクルして新しい動作を追加しただけです。
これは、シングルトンパターンの実装のようです。この関数は静的に呼び出され、静的クラスに変数$_instance
が設定されているかどうかを確認します。
そうでない場合は、それ自体のインスタンス(new self()
)を初期化し、に格納し$_instance
ます。
呼び出すと、すべての呼び出しで同じclassName::getInstance()
クラスインスタンスが取得されます。これが、シングルトンパターンのポイントです。
しかし、これがこのように行われるのを見たことがなく、正直なところ、それが可能であるとは知りませんでした。クラスで何が$_instance
宣言されていますか?
これはシングルトン設計パターンで使用される可能性が最も高く、コンストラクターはインスタンス化を避けるためにプライベートとして定義され、二重コロン(::)
演算子はクラス内で静的に宣言されたメンバーにアクセスできるため、静的メンバーがある場合、疑似変数 $これは使用できないため、コードでは代わりに self を使用しました。Singleton は、データベース コネクタ ハンドラのようなオブジェクトの 1 つのインスタンスのみを許可する優れたプログラミング プラクティスです。クライアントコードから、そのインスタンスへのアクセスは、単一のアクセスポイントを作成することによって行われます.この場合、彼はそれに名前を付けましgetInstance()
た.とも呼ばれている。
行if(!isset(self::instance))
は、オブジェクトが既に作成されているかどうかをチェックします。コードが単なるフラグメントであるため、これを理解できませんでした。上部のどこかに、おそらく次のような静的メンバーがあるはずです。
private static $_instance = NULL;
通常のクラスでは、単純にこのメンバーにアクセスします
$this->_instance = 'something';
しかし、静的に宣言されているため、代わりに使用する $this コードを使用できませんでした
self::$_instance
この静的クラス変数にオブジェクトが格納されているかどうかを確認することにより、クラスは単一のインスタンスを作成するか作成しないかを決定できます。そのため、インスタンスが設定されていない場合、!isset、つまり静的メンバー $_instance にオブジェクトが存在しないことを意味します。新しいオブジェクトを生成$_instance
し、コマンドによって静的メンバーに格納します
self::$_instance = new self();
そしてそれをクライアントコードに返しました。その後、クライアント コードはオブジェクトの単一のインスタンスをそのパブリック メソッドで問題なく使用できますが、クライアント コードでは、単一のアクセス ポイントを呼び出します。つまり、getInstance()
メソッドもトリッキーです。このように呼び出す必要があります。
$thisObject = className::getInstance();
その理由は、関数自体が静的に宣言されているためです。
はい、それはnew className()
(そのメソッドを含むクラスを参照して)似ており、おそらくコンストラクターがプライベートであるシングルトンパターンで使用されます。
クラスが継承されている場合、子から getInstance() を呼び出しても子のインスタンスは得られません。親インスタンスのインスタンスのみを返します。これは、new self() を呼び出すためです。
子クラスが子クラスのインスタンスを返すようにしたい場合は、getInstance() で new static() を使用すると、子クラスのインスタンスが返されます。これは遅延バインディングと呼ばれます!!