GoFデザインパターン23個を完全に理解するブログ #01 Singleton(シングルトン)

2025/10/27

プログラミング

t f B! P L
eyecatch シングルトンとは? アプリ全体で「たった1つだけのインスタンス」を共有するデザインパターンです。 アプリに「設定情報」や「ログ管理」が1つしかないようにしたいときに使う王道のやり方ですね。 手軽に確認しやすい、Javascriptを使ってプログラムを説明したいと思います。

サンプルプログラム

class Config { // staticで唯一のインスタンスを保持 static instance; constructor() { // すでにインスタンスがあれば、それを返す if (Config.instance) { return Config.instance; } // 初回だけ実行される初期化処理 this.settings = { theme: "dark", lang: "ja" }; // 自分自身を静的プロパティに保存 Config.instance = this; } get(key) { return this.settings[key]; } set(key, value) { this.settings[key] = value; } } // --- 実行例 --- const config1 = new Config(); const config2 = new Config(); config1.set("theme", "light"); console.log(config1.get("theme")); // → "light" console.log(config2.get("theme")); // → "light" console.log(config1 === config2); // → true(同じインスタンス)

解説

サンプルプログラムのように、Config.instance というただ1つのインスタンスだけを保持する構造で構築します。 new Config() を何度呼んでも、最初に作られたインスタンスを再利用。 つまり「アプリ全体で1つだけのオブジェクト」を保証するということになります。

このパターンの使われる場面

設定管理(Config) - 全体(グローバル)に対して処理を行う場合。 ログ出力(Logger) - インスタンス別に値を保持しなくてもいい場合。 データベース接続(DB Connection) - システム全体で、同じ振る舞いをする場合。 グローバルなキャッシュ管理 - どのモジュールからアクセスしても、必ず同じ値が取得する場合。

書き方比較

次に、シングルトンをクラスで使う場合と、関数で使う場合を比べてみます。

クラス型シングルトン

上記のサンプルが、クラス型シングルトン。 明示的に「クラス」として扱える(オブジェクト指向寄り)というメリットがあります。 IDEで補完が効きやすいのが特徴で、 newを使う形なので構造が直感的に構築できます。 TypeScriptなどの型サポートと相性が良いので、保守性の高いシステム構築に向いています。

関数型シングルトン

const Config = (function () { let instance; // クロージャ内にインスタンスを保持 function createInstance() { return { settings: { theme: "dark", lang: "ja" }, get(key) { return this.settings[key]; }, set(key, value) { this.settings[key] = value; }, }; } return { getInstance() { if (!instance) { instance = createInstance(); // 初回のみ生成 } return instance; }, }; })(); // --- 利用例 --- const c1 = Config.getInstance(); const c2 = Config.getInstance(); console.log(c1 === c2); // → true(同一インスタンス) この書き方の特徴は、 即時関数+クロージャで「外部から隠す」構造で使われます。 プロトタイプやclassを使わないので軽量で構築できるので、簡易なイベント発火などでのチョイ書きに向いてます。 グローバルスコープを汚さずに済むので関数的プログラミング(FP)スタイルに近いですね。

プライベート・コンストラクタの書き方

Singletonは、グローバルな処理を基本とするため、newさせない方が安定的に処理できるので、その書き方のサンプルコードです。

PHP

class Singleton { private static $instance = null; private function __construct() { // 外部から new できない } public static function getInstance() { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } } $a = Singleton::getInstance();

Javascript

class Singleton { static #instance = null; constructor() { if (Singleton.#instance) { throw new Error("Use getInstance()"); } } static getInstance() { if (!Singleton.#instance) { Singleton.#instance = new Singleton(); } return Singleton.#instance; } } const a = Singleton.getInstance(); Javascriptは、厳密なprivate処理ができないため、constructorでthrow対応するようにしています。

あとがき

比較的シンプルで、よく使われるシングルトンを解説してみました。 書籍などでは、JavaやC言語で解説されているパターンが多いので、 個人的によく作る、Webシステムでサンプルコードを書いてみました。 分かりにくい点などあれば、コメントか、お問い合わせをいただければ、記事追加、修正をしていきたいと思います。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ