2010-02-02 5 views
3

Donc, venant sur le sujet des usines, je me demande comment ils sont mis en place.Comment créez-vous vos usines?

D'où je suis, je peux voir 3 types d'usines:

All In One

Une usine qui contient essentiellement toutes les classes utilisées dans une application. On a l'impression d'avoir une usine pour avoir une usine et on ne se sent pas vraiment structuré.

Exemple (Où ClassA, classe B et ClassC ont rien en commun, sauf être dans la même application):

class Factory 
{ 
public static function buildClassA() 
public static function buildClassB() 
public static function buildClassC() 
} 

Les exemples de code fournis sont en PHP. Cependant, cette question est agnostique.

intégré usine

Le prochain est le mélange dans des fonctions statiques avec les fonctions régulières afin de rendre les modèles de création spéciaux (voir this question)

Exemple:

class ClassA 
{ 
public static function buildClass() 
public function __construct() 
} 

Usine sur le côté

Le dernier que je peux penser est d'avoir une usine pour des classes individuelles, ou des ensembles individuels de classes. Cela semble juste variable pour être utilisé d'une manière uniforme.

Exemple (Où ClassA, B et C sont liés, et 1, 2 et 3 sont liés):

class FactoryAlpha 
{ 
public static function buildClassA() 
public static function buildClassB() 
public static function buildClassC() 
} 

class FactoryNumeric 
{ 
public static function buildClass1() 
public static function buildClass2() 
public static function buildClass3() 
} 

Ma question est: Est-ce toutes ces mauvaises idées, sont l'un d'eux mauvais des idées? Existe-t-il d'autres façons de créer des usines? Certaines de ces idées sont-elles réellement bonnes? Qu'est-ce qu'un bon/meilleur moyen de créer des usines.

+0

En ce qui concerne l'usine intégrée, si vous allez utiliser une fonction statique en tant qu'usine, le constructeur doit probablement être privé. – Duncan

Répondre

5

Le but d'une usine semble être d'avoir le code qui l'utilise pas besoin de savoir quelle classe concrète sera construite (ceci devrait être manipulé en configurant l'usine). Cela semble exclure "All-in One" et "Factory-on-the-Side". J'aime l'approche que les bibliothèques Java utilisent souvent: Vous avez une méthode statique qui crée l'Usine. Factory a une méthode getInstance qui crée l'instance. Cela vous donne deux points de configuration (via les propriétés du système): FactoryImpl par défaut a un certain nombre de paramètres, tels que la classe qu'il doit produire, et si ces options de configuration ne suffisent pas, vous pouvez également remplacer FactoryImpl.

Comme pour "All-in One" vs "Factory-on-the-Side", une usine ne devrait pas produire de classes sans rapport je pense. Encore une fois, en termes Java, chaque usine produit des instances d'une certaine interface. "All-in-One" ressemble à quelque chose qui devrait être remplacé par Dependency Injection (où vous avez un conteneur qui produit toutes sortes d'instances et les injecte dans l'application).

+0

+1 excellente réponse – mxmissile

2

Si vous êtes vraiment intéressé par les "technologies préférées", je les remplacerais toutes par Dependency Injection. Si cela vous semble trop lourd, rappelez-vous que vous ne voyez peut-être pas toutes les utilisations possibles pour votre usine, alors ne créez pas de classe "Nouveau" dans votre usine. Au lieu de cela, avoir un "Setter" qui peut spécifier quelle classe doit être injectée.

Cela sera utile plus tard lorsque vous testez des unités et que vous devez commencer à injecter des classes fictives. Mais comme vous le faites plus général, abstrait et réutilisable, vous finirez par revenir à DI. (Il suffit de ne pas dire que je ne vous préviens)

0

Il n'y a vraiment que deux sortes standard d'usines, au moins selon GOF et les slew de patterns livres qui followed: Le Factory de base, et le Abstract Factory.

Une usine retourne généralement un cas concret que l'appelant fait référence à travers une interface, comme ceci:

// createWidget() here instantiates a BigWidget or SmallWidget or whatever the context calls for 
IWidget widget = WidgetFactory.createWidget(someContextValue); 

En utilisant une usine avec une interface de cette manière maintient l'appelant d'être couplé à un type spécifique de l'objet retourné. Après le vénérable Single Responsibility Principle, une usine devrait faire une chose, c'est-à-dire renvoyer une instance concrète de l'interface demandée, et rien de plus. Une usine de base devrait seulement avoir le travail de créer un type d'objet. D'autre part, l'usine abstraite peut être considérée comme une usine d'usines, et pourrait être plus proche de ce que vous pensiez comme une usine «tout en un». Une fabrique abstraite est généralement configurée au démarrage pour renvoyer un groupe d'usines connexes, par exemple des usines qui pourraient créer une famille particulière d'interfaces graphiques en fonction d'un contexte donné. Ceci est un exemple de Dependency Inversion qui a été largement remplacé par l'utilisation de conteneurs IOC comme Spring.

Questions connexes