重构工厂没有违反开放原则
我有两个基于文章设计的工厂类版本
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;
}
}
版本1:简单,违反开放原则
每当我添加一个新的具体类时,都需要更改SimpleEmployeeFactory
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
}
}
}
版本2:
在我们使用工厂调用之前,重构工厂仍然需要创建具体类
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();
}
}
厂
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();
}
}
客户
Employee emp = SimpleEmployeeFactory.GetEmployee(1);
Activator.CreateInstance(typeof(ChiefTechnologyOfficer)); //Avoid
Employee empFNoR = RefactoredFactory.Instance.createEmployee(5);
你可以看到Activator.CreateInstance(typeof(ChiefTechnologyOfficer))
调用使具体的类在Factory中注册。 否则,我们不能检索对象
有没有办法创建一个不违反OCP原则的工厂类,并创建一个像我在RefactoredFactory类中使用的对象?
它看起来像typeId
患有特征嫉妒 。 相反,定义一个多态类型来捕获类型; 例如界面:
public interface IEmployeeType
{
Employee Create()
}
现在您可以定义例如ManagerType
和TechnicalLeadType
等。示例:
public class ManagerType : IEmployeeType
{
public Employee Create()
{
return new Manager();
}
}
这本质上是一个抽象工厂,它的优点是,当你需要创建一个新的子类型时,你总是可以创建一个新的实现。
如果您处于系统的边界,并且必须将原始值(如整数)转换为多态值,则可以使用角色提示模式之一 - 特别是元数据,角色接口或(我最喜欢的)部分类型名称。
客户
给定一个IEmployeeType
实例employeeType
,客户端只需执行:
Employee emp = employeeType.Create();
Thala,而不是使用静态构造函数,注册方法来填充类型字典。 您可以使用基于配置的解决方案,如.net DbProviderFactory来注册所有类型。
<EmployeeFactories>
<add name="manger" type="Manager, EmployeeAssmbly" />
..
</EmployeeFactories>
链接地址: http://www.djcxy.com/p/77771.html
上一篇: Refactor factory without violating Open Close Principle