ホームページ >バックエンド開発 >PHPチュートリアル >API 開発パート 3: PHP 設計パターン: 完璧なシングルトン パターン
今日はシングルトンパターンについて話しましょう。
私は以前 Java 開発をしていたので、シングルトン モードを使用するときに、最初は空腹の中国スタイルを使用することを考えました。その後、PHP にそのような機能があることに気づきました。クラス定義 クラスのメンバー変数には、非基本型の値が割り当てられます。式、新しい演算など。したがって、ハングリーチャイニーズスタイルは機能しません。代わりに、このシングルトン モードのアトミック性を確保したいと考えました。その結果、PHP には JAVA のようなスレッド セーフティの問題がないことがわかりました。ねえ、PHP は良いと思いますか? OK、それでは PHP の遅延シングルトン モードを試してみましょう。
今はそれについては話さないで、シングルトン モード コードの最初のバージョンから始めましょう:
// 定义私有静态变量.此种方式为:懒汉式单例(PHP中只有这种方式) private static $instance = null; // 私有化构成方法 private function __construct(){ } // 提供获取实例的公共方法 public static function getInstance(){ if(!(self::$instance instanceof self)){ self::$instance = new self(); } return self::$instance; } // 私有__clone方法,禁止复制对象 private function __clone(){ }OK、このコードは完璧に見えます。コメントと書式設定もあり、問題はありません。しかし、使用中に問題を発見しました
私のクラスAはシングルトンモードで、クラスBはクラスAから継承し、次のメソッドを呼び出します:
$a = A::getInstance(); $b = B::getInstance(); var_dump($a === $b);出力結果は次のとおりです。 bool(true)
$b = B::getInstance();を通じて取得されたオブジェクトは依然としてクラス A のオブジェクトであることを意味します。それでは何が起こっているのでしょうか?
問題は self にあります。self の参照は、クラスが定義されたときに決定されます。つまり、A が B を継承しても、その自己参照は依然として A を指します。この問題を解決するために、PHP 5.3 では遅延静的バインディングの機能が導入されました。簡単に言えば、静的メソッドまたは変数は static キーワードを介してアクセスされます。self とは異なり、静的参照は実行時に決定されます。したがって、シングルトン モードを再利用できるようにコードを書き直すだけです。
class C { protected static $_instance = null; protected function __construct(){ } protected function __clone(){ } public function getInstance(){ if (static::$_instance === null) { static::$_instance = new static; } return static::$_instance; } } class D extends C{ protected static $_instance = null; } $c = C::getInstance(); $d = D::getInstance(); var_dump($c === $d);この時の出力は次のようになります: bool(false)
このシングルトンモードを継承している限り、そのサブクラスもシングルトンモードになります。これにより、シングルトン モードが必要になるたびに多くの繰り返しコードを作成する必要がなく、完全な再利用を実現できます。 上記のメソッドは PHP 5.3 でのみ使用できることに注意してください。PHP の以前のバージョンでは、シングルトン クラスごとに getInstance() メソッドを作成することをお勧めします。
上記では、API 開発の 3 番目の部分「PHP 設計パターン: 完璧なシングルトン パターン」を内容の側面も含めて紹介しています。PHP チュートリアルに興味のある友人に役立つことを願っています。