1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonにおけるシングルトン設計パターン:実装例とその適用判断

Posted at

概要

**シングルトンパターン(Singleton Pattern)**は、
「あるクラスのインスタンスが常に1つであること」を保証する設計手法。

設定管理、ログ出力、接続プールなど、状態の一貫性が求められる場面で有効だが、
誤用すればテスト困難・密結合・副作用の温床ともなる。

本稿では Python におけるシングルトンの正統実装と、
適用判断の観点を洗練された設計思考として整理する。


1. シングルトンとは何か?

  • 特定のクラスのインスタンスは「1つだけ」
  • 再生成は同一インスタンスを返す
  • グローバル状態に依存する処理に利用

2. Pythonにおける典型的な実装方法

✅ クラス変数によるインスタンス制御(最もシンプル)

class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance
a = Singleton()
b = Singleton()
assert a is b  # True
  • __new__() によって生成タイミングを制御
  • 1度目は生成、2度目以降は同一インスタンスを返す

✅ デコレータで実現するシングルトン

def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class Config:
    ...

→ 呼び出しインターフェースは通常のクラスと変わらず、設計に柔軟性を与える


✅ モジュールレベルでの自然なシングルトン(Pythonらしい)

# config.py
settings = {
    "DEBUG": True,
    "DB_HOST": "localhost"
}
# app.py
from config import settings

→ Pythonではモジュールは一度しかロードされない
→ 実質的にシングルトンと同じ振る舞いを実現できる


3. シングルトンの使用が適切なケース

  • 設定オブジェクト:全体で一貫した設定状態を保持したい場合
  • ログライター:ファイルや出力先の共有
  • 接続プール・キャッシュ管理:高コストな初期化の回避

4. シングルトンの危険性とその回避法

問題点 説明
密結合になる 多数の箇所が同じオブジェクトに依存する
テストが困難 ステートフルでモック・再生成が難しい
状態汚染が起きやすい 副作用が蓄積されやすい

✅ 解決アプローチ

  • **DI(依存性注入)**により切り替え可能性を確保
  • 明示的なライフサイクル管理で使用範囲を制限
  • テスト時は reset() メソッドや clear() などで状態を初期化

5. 実務でのベストパターン

✅ 設定クラスとしての応用

class AppConfig:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.env = "development"
            cls._instance.debug = True
        return cls._instance

設定変更が即座に全体へ反映される


✅ ログ管理

class Logger:
    _instance = None

    def __new__(cls, filepath="log.txt"):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.filepath = filepath
        return cls._instance

    def log(self, message):
        with open(self.filepath, "a") as f:
            f.write(message + "\n")

結語

シングルトンは、インスタンスの一意性という設計原則をコードで保証する構造である。

  • Pythonでは多様なシングルトン実装が可能
  • 状態の共有と制御を両立するためには、設計意図の明示とテスト性の担保が鍵
  • オブジェクトの数を制御することは、構造と振る舞いの境界線を定義すること

Pythonicとは、“明示的に振る舞いを制限する設計の美学”であり、
シングルトンはその表現の1つに過ぎないが、極めて有力な武器である。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?