Sto cercando un semplice esempio di come implementare una classe factory, ma senza l'uso di uno Switch o di un'istruzione If-Then. Tutti gli esempi che riesco a trovare ne usano uno. Ad esempio, come si può modificare questo semplice esempio (sotto) in modo che la fabbrica effettiva non dipenda dallo Switch? Mi sembra che questo esempio viola il principio di apertura/chiusura. Mi piacerebbe poter aggiungere classi concrete ('Manager', 'Clerk', 'Programmer', ecc.) Senza dover modificare la classe factory.Modello di fabbrica senza interruttore o If/Then
Grazie!
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();
}
}
UPDATE:
Wow! Grazie a tutti! Ho imparato un sacco. Dopo aver ridestato tutto il feedback, ho mescolato alcune delle risposte e ne sono venuto fuori. Sarei aperto a ulteriori dialoghi su un modo migliore per farlo.
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 altro Edit:
E 'anche possibile creare un'istanza della interfaccia utilizzando un tipo sconosciuto:
static class PositionFactory
{
public static IPosition Create(string positionName)
{
Type type = Type.GetType(positionName);
return (IPosition)Activator.CreateInstance(type);
}
}
che potrebbero poi essere chiamato come segue:
IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);
si poteva prendere uno sguardo alla [pattern Abstract Factory] (https: // en.wikipedia.org/wiki/Abstract_factory_pattern) e utilizzare l'iniezione di dipendenza per passare lungo la fabbrica giusta per il lavoro. – Adimeus
Vorrei raccomandare qualcosa come Ninject o Autofac – tdbeckett
Questo è un classico caso di iniezione di dipendenza. L'uso più basilare di qualsiasi contenitore IoC (Unity, Ninject, ecc.) Lo sta usando esattamente come una fabbrica glorificata. – Tanuki