Biorąc pod uwagę, że Python pozwala na wielokrotne dziedziczenie, jak wygląda dziedziczenie idiomatyczne w Pythonie?
W językach z pojedynczym dziedziczeniem, takich jak Java, dziedziczenie byłoby stosowane, gdy można by powiedzieć, że jeden obiekt „jest-a” innego obiektu i chcesz współdzielić kod między obiektami (od obiektu nadrzędnego do obiektu podrzędnego). Na przykład można powiedzieć, że Dog
jest to Animal
:
public class Animal {...}
public class Dog extends Animal {...}
Ale ponieważ Python obsługuje wielokrotne dziedziczenie, możemy utworzyć obiekt, tworząc wiele innych obiektów razem. Rozważ poniższy przykład:
class UserService(object):
def validate_credentials(self, username, password):
# validate the user credentials are correct
pass
class LoggingService(object):
def log_error(self, error):
# log an error
pass
class User(UserService, LoggingService):
def __init__(self, username, password):
self.username = username
self.password = password
def authenticate(self):
if not super().validate_credentials(self.username, self.password):
super().log_error('Invalid credentials supplied')
return False
return True
Czy jest to dopuszczalne lub dobre wykorzystanie wielokrotnego dziedziczenia w Pythonie? Zamiast mówić, że dziedziczenie ma miejsce, gdy jeden obiekt „jest-a” innego obiektu, tworzymy User
model złożony z UserService
i LoggingService
.
Całą logikę operacji bazy danych lub sieci można trzymać osobno od User
modelu, umieszczając je w UserService
obiekcie i zachowując całą logikę logowania LoggingService
.
Widzę pewne problemy z tym podejściem:
- Czy to tworzy obiekt Boga? Skoro
User
dziedziczy lub składa się z niegoUserService
iLoggingService
czy rzeczywiście przestrzega zasady pojedynczej odpowiedzialności? - Aby uzyskać dostęp do metod na obiekcie nadrzędnym / następnym w linii (np.
UserService.validate_credentials
Musimy użyćsuper
. To sprawia, że nieco trudniej jest zobaczyć, który obiekt będzie obsługiwał tę metodę i nie jest tak jasny, jak powiedzmy , tworzenie instancjiUserService
i robienie czegoś takiegoself.user_service.validate_credentials
Jaki byłby Pythoniczny sposób na implementację powyższego kodu?