Singletonパターン
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 71/91。
Singleton Patternは、アプリケーションのライフサイクル全体を通じてclassがinstanceを1つだけ持つことを保証する生成デザインパターンです。また、そのinstanceへのグローバルなアクセスポイントも提供します。
このパターンは、データベース接続、設定マネージャー、ロガーなど、システム全体でアクションを調整するオブジェクトが正確に1つ必要な場合に役立ちます。これらのインスタンスを複数作成すると、リソースを無駄にしたり、一貫性のない動作を引き起こしたりする可能性があります。
PHPでSingletonを実装する方法は次のとおりです:
<?php
class Database {
private static ?Database $instance = null;
private function __construct() {
// プライベートコンストラクタは直接のインスタンス化を防ぎます
}
public static function getInstance(): Database {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function query(string $sql): string {
return "Executing: $sql";
}
}
$db1 = Database::getInstance();
$db2 = Database::getInstance();
echo $db1 === $db2 ? "Same instance" : "Different instances";
出力:
Same instanceこのパターンは、3つの重要な要素に基づいています。private constructor は new を直接使用することを prevents し、static property は単一の instance を保持し、static method は最初の呼び出し時に instance を作成し、その後の呼び出しではそれを returns します。
Singleton を本当に堅牢にするには、cloning と unserialization も prevent する必要があります。
<?php
private function __clone() {}
public function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
チャレンジ
簡単Singleton Patternを使用して設定マネージャーを構築しましょう。実際のアプリケーションでは、通常、設定の単一の信頼できる情報源が必要です。複数の設定オブジェクトがあると、システム全体で一貫性のない動作につながる可能性があります。
コードを2つのファイルに整理します。
Config.php: Singleton Patternを実装するConfigclassを作成します。設定マネージャーは次の要件を満たす必要があります。- 設定をprivate array propertyに保存する
- settings arrayをemptyとしてinitializesするprivate constructorを持つ
- 単一のinstanceをreturnsするstatic
getInstance()methodを提供する __clone()をprivateにすることでcloningをpreventする- 設定を保存するための
set(string $key, string $value): voidmethodを含める - keyに対応するvalueをreturnsし、keyが存在しない場合は
nullをreturnsするget(string $key): ?stringmethodを含める - すべての設定をreturnsする
getAll(): arraymethodを含める
main.php: Config fileをincludeします。2つの入力、keyとvalueを受け取ります。Config instanceを取得し、key
"app_name"とvalue"MyApp"を持つdefault settingを設定します。Config instanceへのsecond referenceを取得し(再度
getInstance()を使用)、入力のkeyとvalueを使って別のsettingを設定します。最後に、Singletonが正しく動作していることを確認します。
- 両方のreferenceがSame objectを指しているかどうかに基づいて、
"Same instance: true"または"Same instance: false"をPrintします(比較には===を使用) - 保存されているsettingの総数を示す
"Settings count: [count]"をPrintします(getAll()の結果に対してcount()を使用) - second referenceを通じてretrievedしたapp_name settingを示す
"App name: [value]"をPrintします
- 両方のreferenceがSame objectを指しているかどうかに基づいて、
このchallengeはSingleton Patternのcore benefitを示しています。getInstance()を何回callしても、常にSame objectが得られるため、アプリケーションのすべての部分が同じconfiguration stateを共有できます。
自分で試してみよう
<?php
require_once 'Config.php';
// 入力を読み取る
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Config インスタンスを取得し、"app_name" を "MyApp" に設定する
// TODO: getInstance() を再度使用して Config への2つ目の参照を取得する
// TODO: 2つ目の参照を使用して、入力からの $key と $value で設定を行う
// TODO: Singleton が機能していることを確認する:
// - Print "Same instance: true" or "Same instance: false" based on === comparison
// - Print "Settings count: [count]" showing total settings
// - 2つ目の参照を通じて取得した app_name を示す "App name: [value]" を出力する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: PHPオンラインコンパイラ