私の経験では、いくつかのパターンはまだPythonで有用であり、静的な言語よりも設定が簡単です。一部のパターンOTOHは、シングルトンパターンのように、必要とされないか、眉をひそめさえします。代わりにモジュールレベルの変数または関数を使用してください。または、Borg Patternを使用します。
Creational Patternを設定する代わりに、オブジェクトを作成するcallableを渡すだけで十分なことがよくあります。Python __call__
には存在せずnew()
、クラス自体の呼び出しであるため、関数、メソッドを持つオブジェクト、またはクラスである可能性があります。
def make_da_thing(maker, other, stuff):
da_thing = maker(other + 1, stuff + 2)
# ... do sth
return da_thing
def maker_func(x, y):
return x * y
class MakerClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
...
a = make_da_thing(maker_func, 5, 8)
b = make_da_thing(MakerClass, 6, 7)
状態と戦略パターンは、C ++やJavaなどの言語で非常によく似た構造を共有しています。Pythonではそうではありません。戦略パターンはほぼ同じままですが、状態パターンはほとんど不要になります。静的言語の状態パターンは、実行時のクラスの変更をシミュレートします。Pythonでは、まさにそれを行うことができます。実行時にオブジェクトのクラスを変更します。制御されたカプセル化された方法でそれを行う限り、大丈夫です:
class On(object):
is_on = True
def switch(self):
self.__class__ = Off
class Off(object):
is_on = False
def switch(self):
self.__class__ = On
...
my_switch = On()
assert my_switch.is_on
my_switch.switch()
assert not my_switch.is_on
Static Type Dispatchに依存するパターンは機能しないか、まったく異なる動作をします。たとえば、Visitor Pattern:などのボイラープレートコードを記述する必要はありません。JavaおよびC ++では、すべての訪問可能クラスでacceptメソッドを記述する必要がありますが、Pythonでは、Visitableなどのmixinクラスを通じてその機能を継承できます。
class Visitable(object):
def accept(self, visitor):
visit = getattr(visitor, 'visit' + self.__class__.__name__)
return visit(self)
...
class On(Visitable):
''' exactly like above '''
class Off(Visitable):
''' exactly like above '''
class SwitchStatePrinter(object): # Visitor
def visitOn(self, switch):
print 'the switch is on'
def visitOff(self, switch):
print 'the switch is off'
class SwitchAllOff(object): # Visitor
def visitOn(self, switch):
switch.switch()
def visitOff(self, switch):
pass
...
print_state = SwitchStatePrinter()
turn_em_off = SwitchAllOff()
for each in my_switches:
each.accept(print_state)
each.accept(turn_em_off)
静的言語でのパターンの適用を必要とする多くの状況は、Pythonではそれほど多くありません。高階関数(デコレータ、関数ファクトリ)またはメタクラスなど、多くのことを他の手法で解決できます。