Modèle de fabrique sans un Commutateur ou Si/Alors
Je suis à la recherche d'un exemple simple de comment mettre en place une usine de classe, mais sans l'utilisation d'un Interrupteur ou d'une instruction if-then. Tous les exemples que je peux trouver en utiliser un. Par exemple, comment pourrait-on modifier ce simple exemple (ci-dessous) de sorte que l'effectif de l'usine ne dépend pas de l'Interrupteur? Il me semble que cet exemple viole les Ouvrir/Fermer le principe. J'aimerais être en mesure d'ajouter des classes concrètes ('Manager', 'Clerk', 'Programmeur', etc) sans avoir à modifier le réglage d'usine de la classe.
Merci!
class Program
{
abstract class Position
{
public abstract string Title { get; }
}
class Manager : Position
{
public override string Title
{
get { return "Manager"; }
}
}
class Clerk : Position
{
public override string Title
{
get { return "Clerk"; }
}
}
class Programmer : Position
{
public override string Title
{
get { return "Programmer"; }
}
}
static class Factory
{
public static Position Get(int id)
{
switch (id)
{
case 0: return new Manager();
case 1: return new Clerk();
case 2: return new Programmer();
default: return new Programmer();
}
}
}
static void Main(string[] args)
{
for (int i = 0; i <= 2; i++)
{
var position = Factory.Get(i);
Console.WriteLine("Where id = {0}, position = {1} ", i, position.Title);
}
Console.ReadLine();
}
}
Mise à JOUR:
Wow! Merci à tous! J'ai appris une tonne. Après revewing tous les commentaires, j'ai mélangé un peu de réponses et est venu avec cette. Je serais prêt à poursuivre le dialogue à propos d'une meilleure façon de le faire.
class Program
{
public interface IPosition
{
string Title { get; }
}
class Manager : IPosition
{
public string Title
{
get { return "Manager"; }
}
}
class Clerk : IPosition
{
public string Title
{
get { return "Clerk"; }
}
}
class Programmer : IPosition
{
public string Title
{
get { return "Programmer"; }
}
}
static class PositionFactory
{
public static T Create<T>() where T : IPosition, new()
{
return new T();
}
}
static void Main(string[] args)
{
IPosition position0 = PositionFactory.Create<Manager>();
Console.WriteLine("0: " + position0.Title);
IPosition position1 = PositionFactory.Create<Clerk>();
Console.WriteLine("1: " + position1.Title);
IPosition position2 = PositionFactory.Create<Programmer>();
Console.WriteLine("1: " + position2.Title);
Console.ReadLine();
}
}
Un Autre Edit:
Il est également possible de créer une instance de l'Interface à l'aide d'un type inconnu:
static class PositionFactory
{
public static IPosition Create(string positionName)
{
Type type = Type.GetType(positionName);
return (IPosition)Activator.CreateInstance(type);
}
}
Qui pourrait être appelé comme suit:
IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);
- Vous pouvez prendre un coup d'oeil à la Résumé de l'Usine Motif et utiliser l'injection de dépendance pour passer le long de la droite d'usine pour le travail.
- Je recommande quelque chose comme Ninject ou Autofac
- C'est un cas classique de l'injection de dépendance. L'utilisation la plus fondamentale de tout conteneur IoC (l'Unité, Ninject, etc...) est précisément en l'utilisant comme une immense Usine.
- J'aimerais voir un exemple d'utilisation de l'Injection de Dépendance et de la Coi. Pourrais-je vous demander de fournir un?
- J'aimerais voir un exemple d'utilisation de l'Injection de Dépendance et de la Coi. Pourrais-je vous demander de fournir un?
- J'ai mis à jour ma réponse afin qu'il utilise des interfaces en fonction de votre demande dans l'un des autres commentaires.
Vous devez vous connecter pour publier un commentaire.
Comment à ce sujet (pas de Dictionnaire requis et la note que vous obtiendrez une erreur de syntaxe si vous essayez de
Create<Position>()
):MODIFIER - mis à Jour pour utiliser un IPosition interface implémentée de manière explicite. Seules les instances de IPosition pouvez accéder aux fonctions de membre (par exemple,
<implementation of Manager>.Title
ne compile pas).EDIT #2 Usine.Créer doit retourner un IPosition pas T lors de l'utilisation de l'interface correctement.
positions
par indice, correspondant grosso modo à l'ids, mais que faire si vous avez besoin de plusieurs distinct les instances d'un "Manager"?Factory.Create<Manager>()
pourquoi ne pas simplement appelernew Manager()
à la place? L'objectif de l'usine modèle est de réduire le couplage entre les composants.Vous pourriez faire usage d'attributs personnalisés et de réflexion.
Dans votre usine, vous pourriez obtenir toutes les classes qui héritent de
Position
et de trouver celle qui a lePositionType
attribut avec la valeur correcte.Utilisée comme ceci:
PositionFactory
. Un résumé de l'usine est juste une usine d'usines, de sorte que vous pourriez utiliser un modèle semblable à cela dans le but de faire un résumé de l'usine. En fait, vous pouvez prendre à la fois des réponses postées jusqu'à présent que les 2 implémentations différentes dePositionFactory
, comme ils l'utiliser presque identiques interfaces, et d'avoir une autre usine qui renvoie unPositionFactory
de l'un ou l'autre type.PositionType
, où cet exemple permet à n'importe quel code pour avoir n'importe quelle positionPourquoi compliquer les choses?
Voici une solution simple:
Ici est de savoir comment le faire sans l'aide de l'usine de classe à tous:
Service Locator Pattern
, seul, sans le "Service"Get
retourne une NOUVELLE instance. Cet exemple renvoie toujours la MÊME instance de chaque type de Poste.