Quand est-ce une bonne idée d'utiliser des méthodes de fabrique dans un objet au lieu d'une classe de fabrique?
design-patterns
factory
factory-pattern
factory-method
Ravindra babu
la source
la source
Réponses:
J'aime penser aux modèles de conception en termes de mes classes étant des «personnes», et les modèles sont les façons dont les gens se parlent.
Donc, pour moi, le modèle d'usine est comme une agence d'embauche. Vous avez quelqu'un qui aura besoin d'un nombre variable de travailleurs. Cette personne peut connaître les informations dont elle a besoin chez les personnes qu'elle embauche, mais c'est tout.
Ainsi, lorsqu'ils ont besoin d'un nouvel employé, ils appellent l'agence d'embauche et leur disent ce dont ils ont besoin. Maintenant, pour réellement embaucher quelqu'un, vous devez connaître beaucoup de choses - avantages sociaux, vérification de l'admissibilité, etc. Mais la personne qui embauche n'a pas besoin de savoir tout cela - l'agence d'embauche gère tout cela.
De la même manière, l'utilisation d'une usine permet au consommateur de créer de nouveaux objets sans avoir à connaître les détails de la façon dont ils ont été créés, ni quelles sont leurs dépendances - ils n'ont qu'à fournir les informations qu'ils souhaitent réellement.
Ainsi, maintenant, le consommateur de la ThingFactory peut obtenir une chose, sans avoir à connaître les dépendances de la chose, à l'exception des données de chaîne qui proviennent du consommateur.
la source
within an object instead of a Factory class
. Je pense qu'il voulait dire le scénario où vous rendez le ctor privé et utilisez une méthode statique pour instancier la classe (créer un objet). Mais pour suivre cet exemple, il faut d'abord instancier laThingFactory
classe pour obtenir desThing
objets, ce qui en fait unFactory class
effet.Les méthodes d'usine devraient être considérées comme une alternative aux constructeurs - surtout lorsque les constructeurs ne sont pas assez expressifs, c'est-à-dire.
n'est pas aussi expressif que:
Les classes d'usine sont utiles lorsque vous avez besoin d'un processus compliqué pour construire l'objet, lorsque la construction a besoin d'une dépendance que vous ne voulez pas pour la classe réelle, lorsque vous devez construire différents objets, etc.
la source
Une situation où je trouve personnellement des classes Factory distinctes pour donner un sens est lorsque l'objet final que vous essayez de créer repose sur plusieurs autres objets. Par exemple, en PHP: Supposons que vous ayez un
House
objet, qui à son tour a unKitchen
et unLivingRoom
objet, et que l'LivingRoom
objet ait également unTV
objet à l'intérieur.La méthode la plus simple pour y parvenir est que chaque objet crée ses enfants sur sa méthode de construction, mais si les propriétés sont relativement imbriquées, lorsque votre
House
création échoue, vous passerez probablement un certain temps à essayer d'isoler exactement ce qui échoue.L'alternative est de faire ce qui suit (injection de dépendance, si vous aimez le terme de fantaisie):
Ici, si le processus de création d'un
House
échoue, il n'y a qu'un seul endroit où chercher, mais devoir utiliser ce morceau chaque fois que l'on veut un nouveauHouse
est loin d'être pratique. Entrez dans les usines:Grâce à l'usine ici, le processus de création d'un
House
est abstrait (en ce que vous n'avez pas besoin de créer et de configurer chaque dépendance unique lorsque vous voulez simplement créer unHouse
) et en même temps centralisé, ce qui facilite la maintenance. Il y a d'autres raisons pour lesquelles l'utilisation d'usines séparées peut être bénéfique (par exemple la testabilité) mais je trouve ce cas d'utilisation spécifique pour illustrer au mieux comment les classes d'usine peuvent être utiles.la source
HouseFactory
classe?create
méthode. Par exemple, si votreHouse
va toujours avoir le même type,LivingRoom
il peut être judicieux de coder en dur ses paramètres dans la classe d'usine plutôt que de les passer comme arguments. Ou vous pouvez vouloir fournir untype
argument à votreHouseFactory::create
méthode si vous avez quelques types deLivingRoom
s et avez un commutateur à l'intérieur avec les paramètres codés en dur pour chaque type.Il est important de différencier clairement l'idée derrière l'utilisation de l'usine ou de la méthode d'usine. Les deux sont destinés à résoudre différents types de problèmes de création d'objets mutuellement exclusifs.
Soyons précis sur la "méthode d'usine":
La première chose est que, lorsque vous développez une bibliothèque ou des API qui seront à leur tour utilisées pour le développement d'applications ultérieures, la méthode d'usine est l'une des meilleures sélections pour le modèle de création. Raison derrière; Nous savons que quand créer un objet avec les fonctionnalités requises, mais le type d'objet restera indécis ou il sera décidé que les paramètres dynamiques seront passés .
Maintenant, le fait est qu'environ la même chose peut être obtenue en utilisant le modèle d'usine lui-même, mais un énorme inconvénient introduira dans le système si le modèle d'usine sera utilisé pour le problème mis en évidence ci-dessus, c'est que votre logique de création d'objets différents (objets de sous-classes) être spécifique à certaines conditions commerciales, donc à l'avenir lorsque vous aurez besoin d'étendre les fonctionnalités de votre bibliothèque pour d'autres plates-formes (plus techniquement, vous devez ajouter plus de sous-classes d'interface de base ou de classe abstraite afin que l'usine renvoie également ces objets en plus de ceux existants) sur la base de certains paramètres dynamiques), puis chaque fois que vous devez modifier (étendre) la logique de la classe d'usine, ce qui sera coûteux et pas bon du point de vue de la conception. De l'autre côté, si "méthode d'usine"
la source
Ils sont également utiles lorsque vous avez besoin de plusieurs "constructeurs" avec le même type de paramètre mais avec un comportement différent.
la source
C'est une bonne idée d'utiliser des méthodes d'usine à l' intérieur de l'objet lorsque:
C'est une bonne idée d'utiliser la classe d' usine abstraite lorsque:
la source
UML à partir de
Produit: Il définit une interface des objets créés par la méthode Factory.
ConcreteProduct: implémente l'interface produit
Créateur: déclare la méthode Factory
ConcreateCreator: implémente la méthode Factory pour renvoyer une instance d'un ConcreteProduct
Énoncé du problème: créez une usine de jeux à l'aide des méthodes d'usine, qui définissent l'interface de jeu.
Extrait de code:
production:
Cet exemple montre une
Factory
classe en implémentant unFactoryMethod
.Game
est l'interface pour tous les types de jeux. Il définit une méthode complexe:createGame()
Chess, Ludo, Checkers
sont différentes variantes de jeux, qui permettent la mise en œuvre decreateGame()
public Game getGame(String gameName)
estFactoryMethod
enIGameFactory
classeGameFactory
pré-crée différents types de jeux dans le constructeur. Il implémente laIGameFactory
méthode d'usine.le nom du jeu est passé comme argument de ligne de commande à
NotStaticFactoryDemo
getGame
inGameFactory
accepte un nom de jeu et renvoie l'Game
objet correspondant .Usine:
FactoryMethod
Cas d'utilisation:
Quand l'utiliser:
Client
ne sait pas quelles classes concrètes il devra créer au moment de l'exécution, mais veut juste obtenir une classe qui fera le travail.la source
getArea()
n'est pas une méthode de fabrication du tout .C'est vraiment une question de goût. Les classes d'usine peuvent être abstraites / interfacées si nécessaire, tandis que les méthodes d'usine sont plus légères (et ont également tendance à être testables, car elles n'ont pas de type défini, mais elles nécessiteront un point d'enregistrement bien connu, semblable à un service localisateur mais pour localiser les méthodes d'usine).
la source
Les classes de fabrique sont utiles lorsque le type d'objet qu'elles renvoient a un constructeur privé, lorsque différentes classes de fabrique définissent des propriétés différentes sur l'objet renvoyé ou lorsqu'un type de fabrique spécifique est couplé avec son type de béton de retour.
WCF utilise les classes ServiceHostFactory pour récupérer des objets ServiceHost dans différentes situations. Le ServiceHostFactory standard est utilisé par IIS pour récupérer des instances ServiceHost pour les fichiers .svc , mais un WebScriptServiceHostFactory est utilisé pour les services qui renvoient des sérialisations aux clients JavaScript. ADO.NET Data Services a son propre DataServiceHostFactory spécial et ASP.NET a son ApplicationServicesHostFactory car ses services ont des constructeurs privés.
Si vous n'avez qu'une seule classe qui consomme l'usine, vous pouvez simplement utiliser une méthode d'usine dans cette classe.
la source
Envisagez un scénario lorsque vous devez concevoir une classe Commande et Client. Pour des raisons de simplicité et d'exigences initiales, vous ne ressentez pas le besoin d'usine pour la classe Order et remplissez votre application avec de nombreuses instructions 'new Order ()'. Les choses fonctionnent bien.
Maintenant, une nouvelle exigence entre en scène: l'objet Order ne peut pas être instancié sans association Client (nouvelle dépendance). Vous avez maintenant les considérations suivantes.
1- Vous créez une surcharge de constructeur qui ne fonctionnera que pour les nouvelles implémentations. (Pas acceptable). 2- Vous modifiez les signatures Order () et modifiez chaque invocation. (Pas une bonne pratique et une vraie douleur).
Au lieu de cela, si vous avez créé une usine pour Order Class, vous n'avez qu'à modifier une ligne de code et vous êtes prêt à partir. Je suggère la classe Factory pour presque toutes les associations d'agrégats. J'espère que cela pourra aider.
la source
si vous souhaitez créer un objet différent en termes d'utilisation. C'est utile.
la source
Toute classe reportant la création d'objet à sa sous-classe pour l'objet avec lequel elle doit travailler peut être considérée comme un exemple de modèle Factory.
J'ai mentionné en détail dans une autre réponse à https://stackoverflow.com/a/49110001/504133
la source
Je pense que cela dépendra du degré de couplage lâche que vous souhaitez apporter à votre code.
La méthode d'usine dissocie très bien les choses, mais la classe d'usine non.
En d'autres termes, il est plus facile de changer les choses si vous utilisez la méthode d'usine que si vous utilisez une usine simple (connue sous le nom de classe d'usine).
Regardez cet exemple: https://connected2know.com/programming/java-factory-pattern/ . Maintenant, imaginez que vous voulez amener un nouvel animal. Dans la classe Factory, vous devez changer Factory, mais dans la méthode Factory, non, vous avez seulement besoin d'ajouter une nouvelle sous-classe.
la source
Les classes d'usine sont plus lourdes, mais vous offrent certains avantages. Dans les cas où vous devez créer vos objets à partir de plusieurs sources de données brutes, ils vous permettent d'encapsuler uniquement la logique de construction (et peut-être l'agrégation des données) en un seul endroit. Là, il peut être testé de manière abstraite sans se préoccuper de l'interface objet.
J'ai trouvé cela un modèle utile, en particulier lorsque je suis incapable de remplacer et d'ORM inadéquat et que je souhaite instancier efficacement de nombreux objets à partir de jointures de table DB ou de procédures stockées.
la source
Je compare les usines au concept de bibliothèques. Par exemple, vous pouvez avoir une bibliothèque pour travailler avec des nombres et une autre pour travailler avec des formes. Vous pouvez stocker les fonctions de ces bibliothèques dans des répertoires logiquement nommés
Numbers
ouShapes
. Ce sont des types génériques qui pourraient inclure des entiers, des flottants, des dobules, des longs ou des rectangles, des cercles, des triangles, des pentagones dans le cas des formes.Le petter d'usine utilise le polymorphisme, l'injection de dépendance et l'inversion de contrôle.
Le but déclaré des modèles d'usine est:
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Supposons donc que vous construisez un système d'exploitation ou une infrastructure et que vous construisez tous les composants discrets.
Voici un exemple simple du concept du Factory Pattern en PHP. Je ne suis peut-être pas à 100% sur tout cela, mais il est destiné à servir d'exemple simple. Je ne suis pas un expert.
la source
NumbersFactory::makeNumber( 'float', 12.5 );
ce qui me donne juste de direnew Float(12.5);
si je sais que j'ai besoin d'unFloat
? C'est ce que je ne comprends pas des usines ... à quoi ça sert?