Modèle d'usine abstrait en Python
J'ai lu aujourd'hui sur le modèle d'usine abstrait et j'ai essayé de faire l'implémentation suivante.
J'ai vu beaucoup d'implémentations sur Internet, où ils utilisent des switch
déclarations, mais je dois dire que je n'ai pas trop aimé, car plus vous fabriquez d'usines, il me semble que cela rend très difficile l'ajout de nouveaux produits, si besoin.
Quoi qu'il en soit, j'espérais que vous y jetteriez un coup d'œil et que vous me donneriez votre avis. Merci d'avance d'avoir pris le temps de l'examiner.
Des usines
from abc import ABC, abstractmethod
class PlayerFactory(ABC):
"""
This class is meant to be an interface
"""
@abstractmethod
def create_goalkeeper(self):
pass
@abstractmethod
def create_defender(self):
pass
class FootballPlayerFactory(PlayerFactory):
def create_goalkeeper(self):
return FootballGoalkeeper()
def create_defender(self):
return FootballDefender()
class HockeyPlayerFactory(PlayerFactory):
def create_goalkeeper(self):
return HockeyGoalkeeper()
def create_defender(self):
return HockeyDefender()
Joueurs de football
class FootballPlayer:
def __init__(self, uses_hands):
self.uses_hands = uses_hands
def play(self):
print("I'm playing football!")
class FootballGoalkeeper(FootballPlayer):
def __init__(self):
super(FootballGoalkeeper, self).__init__(uses_hands=True)
class FootballDefender(FootballPlayer):
def __init__(self):
super(FootballDefender, self).__init__(uses_hands=False)
Joueurs de hockey ( ma créativité s'est arrêtée là, donc je n'ai pas inclus de différence entre les gardiens et les défenseurs )
class HockeyPlayer:
def play(self):
print("I'm playing hockey!")
class HockeyGoalkeeper(HockeyPlayer):
pass
class HockeyDefender(HockeyPlayer):
pass
Réponses
Dans l'état actuel de votre code, vous n'avez pas besoin des classes Factory dérivées. Ils ne font rien de différent les uns des autres, ils peuvent donc tous être gérés par une classe de base concrète.
class PlayerFactory:
def __init__(self, goal_keeper_class, defender_class):
self._goal_keeper_class = goal_keeper_class
self._defender_class = defender_class
def create_goalkeeper(self):
return self._goal_keeper_class()
def create_defender(self):
return self._defender_class()
player_factory = {
"Football": PlayerFactory(FootballGoalkeeper, FootballDefender),
"Hockey": PlayerFactory(HockeyGoalkeeper, HockeyDefender),
}
Exemple d'utilisation :
>>> player = player_factory["Hockey"].create_defender()
>>> type(player)
<class '__main__.HockeyDefender'>
>>> player.play()
I'm playing hockey!
>>>
S'il y a un aspect des usines qui fait quelque chose de différent et nécessite donc des classes dérivées séparées, vous devrez l'inclure dans votre question.