在不违反开闭原则的情况下重构工厂
本文关键字:情况下 重构 工厂 原则 | 更新日期: 2023-09-27 17:49:33
我有两个基于文章
设计的工厂类版本http://www.oodesign.com/factory-pattern.htmlpublic 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))
调用使具体类向工厂注册自己。否则我们无法检索对象
有没有一种方法可以在不违反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();
不使用静态构造函数,而是使用注册方法来填充类型字典。你可以使用基于配置的解决方案,如。net DbProviderFactory,来注册所有类型。
<EmployeeFactories>
<add name="manger" type="Manager, EmployeeAssmbly" />
..
</EmployeeFactories>