I'm looking for a simple example of how to implement a factory class, but without the use of a Switch or an If-Then statement. All the examples I can find use one. For example, how could one modify this simple example (below) so that the actual factory does not depend on the Switch? It seems to me that this example violates the Open/Close principle. I'd like to be able to add concrete classes ('Manager', 'Clerk', 'Programmer', etc) without having to modify the factory class.
Thanks!
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! Thanks everyone! I have learned a ton. After revewing all the feedback, I blended a few of the answers and came up with this. I'd be open to further dialog about a better way to do this.
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();
}
}
Another Edit:
It's also possible to create an instance of the Interface using an unknown type:
static class PositionFactory
{
public static IPosition Create(string positionName)
{
Type type = Type.GetType(positionName);
return (IPosition)Activator.CreateInstance(type);
}
}
Which could then be called as follows:
IPosition position = PositionFactory.Create("Manager");
Console.WriteLine(position.Title);