11.5.3例シングルトンパターン

シングルトンパターンは、デザインパターンの一つで、特定のクラスがプログラム中で1つしかインスタンスを持たないことを保証するためのパターンです。主な目的は、一つのインスタンスから簡単にアクセスできるようにすることと、同時にそのインスタンスの多重生成を防ぐことです。

シングルトンパターンの主な特徴や利点は以下の通りです:

  1. 一意性: クラスのインスタンスは1つだけ生成されます。
  2. グローバルアクセス: その唯一のインスタンスはアプリケーションのどこからでもアクセス可能です。
  3. 遅延初期化: 必要になるまでインスタンスの生成を遅延することができます。

シングルトンパターンが役立つシチュエーションの例:

  • 設定やプロパティの共有: アプリケーション全体で共有する設定やプロパティを持つ場合。
  • リソースの共有: 同じリソースに対する複数のアクセスを制御する必要がある場合(例:ファイルハンドラ、ネットワーク接続など)。
  • ロギング: 全てのコンポーネントからアクセス可能な一つのログインスタンスを持つ場合。
>>> class SingletonMeta(type):
...    #実クラスにクラス変数を追加
...    def __init__(cls, name, bases, disc, **kwargs):
...       cls.__instance = None
...    #実クラスをインスタンス化する際の処理を追加
...    def __call__(cls, *args, **kwargs):
...       if cls.__instance is None:
...          cls.__instance = super().__call__(*args, **kwargs)
...       return cls.__instance
...
>>> class MySingleton(metaclass=SingletonMeta):
...    pass
...
>>> if __name__ == '__main__':
...    c1 = MySingleton()
...    c2 = MySingleton()
...    print(c1 is c2)
...
True
  1. メタクラスの使用:

    • Pythonでは、クラスの振る舞いそのものをカスタマイズするためにメタクラスを使用できます。この例では、SingletonMetaというメタクラスを定義しています。
  2. __init__メソッド:

    • SingletonMeta内の__init__メソッドは、新しいクラスが定義された際に呼び出されます。
    • このメソッド内で、cls.__instanceというクラス変数をNoneに初期化しています。この変数は、シングルトンインスタンスを保持するために使います。
  3. __call__メソッド:

    • __call__メソッドは、クラスがインスタンス化される際に呼び出されます。
    • このメソッド内で、cls.__instanceNone(つまり、シングルトンインスタンスがまだ作成されていない)かどうかをチェックします。
    • シングルトンインスタンスが存在しない場合、新しいインスタンスを作成してcls.__instanceに保存します。
    • 最後に、cls.__instanceを返します。これにより、クラスが何度インスタンス化されても、常に同じインスタンスが返されます。
  4. シングルトンクラスの作成:

    • MySingletonクラスは、metaclass引数にSingletonMetaを指定して定義されています。これにより、MySingletonクラスはSingletonMetaの振る舞いを継承します。
  5. テスト:

    • __main__ブロック内で、MySingletonクラスを2回インスタンス化していますが、2つのインスタンスが実際には同一であることを確認するためにc1 is c2を評価しています。この結果はTrueとなります。

この実装により、シングルトンパターンの目的、すなわちクラスのインスタンスが一つしか存在しないことを保証することが達成されています。