Modèle d'usine abstrait en Python

Aug 17 2020

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 switchdé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

2 AJNeufeld Aug 17 2020 at 22:24

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.