Pythonで学ぶデザインパターン入門 Singletonパターン
結城先生の Java言語で学ぶデザインパターン入門
のコードを Python に書き直していくシリーズ第5段です。
Singletonパターンとは
定義した範囲内で、そのものが1つしか存在しないことを保証するパターンです。
よくある例でいうと、実行環境内でインスタンス1個以上作られないことを保証するといったことをよくやります。
具体的には、クラスAのインスタンスAを作った後に、もう一度クラスAからインスタンスを生成したらインスタンスAがそのまま返されるという形のものです。
普通なら、別のインスタンスが返りますが、シングルトンパターンの場合は絶対にそのインスタンスを1個以上存在させることはしません。
ソースコード
コードの概要
パターン説明の際に紹介した具体例を実装します。
常にインスタンスが1個しか作られないことを保証するといった動作のものです。
こういった仕組みは言語特有の機能を利用するものが多く、 Java言語で学ぶデザインパターン入門
はJava特有の機能を利用したものでした。
なので今回に関しては本のコードを写経するわけではなく、 Python
特有のシングルトンパターンの実装を紹介します。
ソースコード
Singleton クラス
# coding: utf-8 import threading class Singleton(object): _instance = None _lock = threading.Lock() def __new__(cls, *args, **kwargs): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance def __init__(self): print('initメソッドは毎回呼ばれるので注意')
Pythonでいうコンストラクタは __init__
ですが、インスタンス生成時に __new__
というメソッドが呼び出されます。
今回はそれを上書きして、クラス変数を利用して必ず1個しかインスタンスを保持しないような形にしました。
cls._instance
がない場合だけ、スーパークラスにもともと存在しているインスタンス生成メソッドを呼び出す形です。
しかし、もともとのコンストラクタの __init__
は毎回呼び出されてしまうことに注意してください。
_lock = threading.Lock()
は、マルチスレッドを考慮した制限になります。
実行ファイル
# coding: utf-8 from Singleton.singleton import Singleton if __name__ == '__main__': s1 = Singleton() s2 = Singleton() if s1 is s2: print('Singleton') else: print('Not Singleton')
Singleton
と表示されたらOKですね。
シングルトンパターンじゃなかったら別のインスタンスになるので Not Singleton
と表示されてしまいます。
実際どう便利か
このパターンはいろいろなところで利用することが想定されるパターンです。
たとえば、お金の計算処理などは同じデータに2回も処理が入ってはいけません。
そのようなケースは実際には多々に存在します。
むしろインスタンスを1個だけに限定するパターンは紹介には使われますが実際にはそこまで利用されることはないかもしれませんね。