gpt4 book ai didi

c# - 在不违反开闭原则的情况下重构工厂

转载 作者:太空狗 更新时间:2023-10-29 23:31:19 26 4
gpt4 key购买 nike

我根据文章设计了两个版本的工厂类

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)) 调用使具体类向工厂注册自己。否则我们无法检索对象

有没有一种方法可以在不违反 OCP 原则的情况下创建工厂类并且不创建像我在 RefactoredFactory 类中使​​用的对象那样的对象?

最佳答案

看起来 typeId 受到了Feature Envy 的困扰。相反,定义一个多态类型来捕获类型;例如一个接口(interface):

public interface IEmployeeType
{
Employee Create()
}

现在您可以定义例如ManagerTypeTechnicalLeadType 等。示例:

public class ManagerType : IEmployeeType
{
public Employee Create()
{
return new Manager();
}
}

这本质上是一个 Abstract Factory ,它的优点是当您需要创建一个新的子类型时,您总是可以创建一个新的实现。

如果您处于系统的边界,并且必须将原始值(如整数)转换为多态值,您可以使用 Role Hint patterns 之一- 特别是 Metadata , Role Interface ,或(我最喜欢的)Partial Type Name .

客户端

给定一个 IEmployeeType 实例 employeeType,客户端会简单地去:

Employee emp = employeeType.Create();

关于c# - 在不违反开闭原则的情况下重构工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22326210/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com