Singletonパターン (1)
『Rubyによるデザインパターン』(ラス・オルセン著 ピアソン・エデュケーション刊)の例をPythonに変換して書いています。目次
- Singletonパターン (1)
- Singletonパターン (2) - ぜ〜んぶクラスメソッド
- Singletonパターン (3) - モジュール
- Singletonパターン (4) - メタクラスを使った方法
- Singletonパターン (5) - Borgの方法
Singletonパターンは「インスタンスが同時に2個以上存在しない」クラスを作るパターンです。
正直、Singletonを何時使うのか、私には分かりません。別に無くても良いように思えます。
しかし、Singletonは有名なようです。「python singleton」で検索すると、例がウジャウジャ出てきます。「python strategy」など、このサイトが上から4番目に上がるほどなのに・・・。
まずは、古典的なSingletonパターンの実装です。
#いわゆるSingleton class Singleton(object): _instance = None def __new__(cls, *a, **kw): if cls._instance is None: cls._instance = object.__new__(cls, *a, **kw) return cls._instance def set_name(self, name): self.name = name def get_name(self): return self.name s1 = Singleton() s2 = Singleton() s1.set_name("egg") s2.set_name("spam") print s1.get_name() #=> spam print s2.get_name() #=> spam
Singletonパターンの問題は、サブクラス化の時に顔を出します。
class Example(Singleton): def set_name(self, name): Singleton.set_name(name*2) a = Singleton() b = Singleton() c = Example() c.set_name("aaaa") print c.get_name() #=> aaaa #あれ〜?
Singletonクラスは2個以上のインスタンスを持ちません。
つまり、Singletonのインスタンスが既に存在するのに、
新たにインスタンスを作ろうとしても、既存のSingletonのインスタンスが返されます。
そして、サブクラスExampleのインスタンスは、同時にSingletonのインスタンスでもあります。
よってSingletonのインスタンスが既にあるときに、
Exampleのインスタンスを作ろうとしても、既存のSingletonのインスタンスが返されるのです。
つまり・・・
a = Singleton() b = Singleton() c = Example() print c #=> <__main__.Singleton object at 0x00B014F0>
また、Singletonパターンのどこからでも同じ物を参照できるという性質は、グローバル変数と同じです。
Singletonのグローバル変数より優れている点は、インスタンス最大数を調整できる事です。
Singleton.__new__をちょっと改良すれば、高々20しかインスタンスが存在しないクラスを作るのは簡単です。
しかし、プログラムの結合度が増すという点では同じです。Singletonを使う前に、よくよく検討するべきでしょう。