Padrão Abstrato de Fábrica em Python
Estive lendo hoje sobre o Abstract Factory Pattern e tentei fazer a seguinte implementação.
Já vi muitas implementações na internet, onde usam switch
declarações, mas devo dizer que não gostei muito, pois quanto mais fábricas você faz, me parece que dificulta muito a adição de novos produtos, se necessário.
De qualquer forma, eu estava esperando que você desse uma olhada e me desse sua opinião. Agradecemos antecipadamente por dedicar seu tempo para revisá-lo.
Fábricas
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()
Jogadores de futebol
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)
Jogadores de hóquei ( minha criatividade parou aqui, então não incluí nenhuma diferença entre goleiros e zagueiros )
class HockeyPlayer:
def play(self):
print("I'm playing hockey!")
class HockeyGoalkeeper(HockeyPlayer):
pass
class HockeyDefender(HockeyPlayer):
pass
Respostas
Como seu código está atualmente, você não precisa das classes Factory derivadas. Eles não fazem nada diferente um do outro, então todos podem ser tratados por uma classe base concreta.
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),
}
Exemplo de uso:
>>> player = player_factory["Hockey"].create_defender()
>>> type(player)
<class '__main__.HockeyDefender'>
>>> player.play()
I'm playing hockey!
>>>
Se houver algum aspecto das fábricas que realmente fazem algo diferente e, portanto, necessitam de classes derivadas separadas, você precisará incluir isso em sua pergunta.