Z mojego doświadczenia wynika, że niektóre wzorce są nadal przydatne w Pythonie, a nawet łatwiejsze w konfiguracji niż w bardziej statycznych językach. Niektóre Wzory OTOH są po prostu niepotrzebne, a nawet marszczone, jak Wzorzec Singleton. Zamiast tego użyj zmiennej lub funkcji na poziomie modułu. Lub użyj Wzoru Borga.
Zamiast konfigurować Wzorzec Kreatywny, często wystarczy przekazać dookoła wywołanie, które tworzy obiekty. Może to być funkcja, obiekt z __call__
metodą lub nawet klasą, ponieważ new()
w Pythonie nie ma , tylko wywołanie samej klasy:
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)
Wzorzec stanu i strategii ma bardzo podobną strukturę w językach takich jak C ++ i Java. Mniej w Pythonie. Wzorzec strategii pozostaje mniej więcej taki sam, ale Wzorzec stanu staje się w większości niepotrzebny. Wzorzec stanu w językach statycznych symuluje zmianę klasy w czasie wykonywania. W Pythonie możesz to zrobić: zmienić klasę obiektu w czasie wykonywania. Tak długo, jak robisz to w kontrolowany, zamknięty sposób, wszystko powinno być w porządku:
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
Wzory oparte na statycznej wysyłce typów nie będą działać lub będą działać zupełnie inaczej. Nie musisz pisać zbyt dużo kodu płyty kotłowej, np. Wzorzec gościa: w Javie i C ++ musisz napisać metodę akceptacji w każdej odwiedzalnej klasie, natomiast w Pythonie możesz odziedziczyć tę funkcjonalność poprzez klasę mixin, np. Visitable:
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)
Wiele sytuacji, które wymagają zastosowania Wzorca w Języku Statycznym, nie robi tego tak często w Pythonie. Wiele rzeczy można rozwiązać za pomocą innych technik, takich jak funkcje wyższego rzędu (dekoratorzy, fabryki funkcji) lub meta-klasy.