Ich bin auf der Suche nach einem einfachen Beispiel, wie eine Factory-Klasse zu implementieren, aber ohne die Verwendung eines Schalters oder eine Wenn-Dann-Anweisung. Alle Beispiele, die ich finden kann, benutzen eins. Zum Beispiel, wie könnte man dieses einfache Beispiel ändern (unten), so dass die tatsächliche Fabrik nicht vom Switch abhängig ist? Es scheint mir, dass dieses Beispiel das Open/Close-Prinzip verletzt. Ich möchte in der Lage sein, konkrete Klassen ('Manager', 'Clerk', 'Programmer' usw.) hinzuzufügen, ohne die Factory-Klasse ändern zu müssen.Factory Pattern ohne einen Schalter oder wenn/dann
Danke!
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! Danke allen! Ich habe eine Tonne gelernt. Nachdem ich alle Rückmeldungen erhalten hatte, mischte ich einige der Antworten ein und kam auf diese Idee. Ich wäre offen für einen weiteren Dialog über einen besseren Weg, dies zu tun.
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();
}
}
Ein weiterer Edit:
Es ist auch möglich, eine Instanz der Schnittstelle mit Hilfe eines unbekannten Typs zu erstellen:
static class PositionFactory
{
public static IPosition Create(string positionName)
{
Type type = Type.GetType(positionName);
return (IPosition)Activator.CreateInstance(type);
}
}
die dann wie folgt genannt werden:
IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);
Sie am [Abstract Factory Pattern] einen Blick darauf werfen konnte (https: // en.wikipedia.org/wiki/Abstract_factory_pattern) und verwenden Sie die Abhängigkeitsinjektion, um die richtige Fabrik für den Job zu übergeben. – Adimeus
Ich würde so etwas wie Ninject oder Autofac empfehlen – tdbeckett
Dies ist ein klassischer Fall der Abhängigkeitsinjektion. Die einfachste Verwendung eines IoC-Containers (Unity, Ninject, etc ...) besteht darin, ihn genau als eine verklärte Fabrik zu verwenden. – Tanuki