I have two versions of a factory class designed based on the article
http://www.oodesign.com/factory-pattern.html
public abstract class Employee
{
public string Name { get; set; }
protected string Role { get; set; }
public abstract string GetRole();
}
public class Manager : Employee
{
public Manager()
{
Role = "MGR";
}
public override string GetRole()
{
return this.Role;
}
}
Version 1: Simple, Violates Open Close Principle
Need to change SimpleEmployeeFactory every time, when I add a new concrete class
public class SimpleEmployeeFactory
{
public static Employee GetEmployee(int typeId)
{
switch (typeId)
{
case 1:
return new Manager();
case 2:
return new TechnicalLead();
default:
return null; //if the id doesn't have any
}
}
}
Version 2:
Refactored Factory, still needs a Concrete Class creation, before we use factory call
public abstract class Employee
{
public string Name { get; set; }
protected string Role { get; set; }
public abstract string GetRole();
public abstract Employee createEmployee();
}
public class ChiefTechnologyOfficer : Employee
{
public ChiefTechnologyOfficer()
{
this.Role = "CTO";
}
static ChiefTechnologyOfficer()
{
RefactoredFactory.Instance.registerEmployee(5, new ChiefTechnologyOfficer());
}
public override string GetRole()
{
return this.Role;
}
public override Employee createEmployee()
{
return new ChiefTechnologyOfficer();
}
}
Factory
class RefactoredFactory
{
private static readonly RefactoredFactory instance = new RefactoredFactory();
static RefactoredFactory()
{
}
private RefactoredFactory()
{
}
public static RefactoredFactory Instance
{
get
{
return instance;
}
}
private Dictionary<int, Employee> registeredEmployees = new Dictionary<int, Employee>();
public void registerEmployee(int typeId, Employee employeeInst)
{
registeredEmployees.Add(typeId, employeeInst);
}
public Employee createEmployee(int typeId)
{
return ((Employee)registeredEmployees[typeId]).createEmployee();
}
}
Client
Employee emp = SimpleEmployeeFactory.GetEmployee(1);
Activator.CreateInstance(typeof(ChiefTechnologyOfficer)); //Avoid
Employee empFNoR = RefactoredFactory.Instance.createEmployee(5);
You can see Activator.CreateInstance(typeof(ChiefTechnologyOfficer))
call to make the concrete classes to register themselves with the Factory. Otherwise we cant retrieve the object
Is there a way to create a Factory class with out violating OCP principle & with out creating an object like the one I used in RefactoredFactory class?