重构问题指导

本文关键字:问题 重构 | 更新日期: 2023-09-27 18:29:06

我有几个方法,确切地说是10个。所有这些都有相同的返回类型,并接受相同的参数,如

公共字符串GenerateDataForABC(列表模型列表,学生)

除了一些自定义之外,它们几乎都做相同的事情,即返回一个字符串。

例如,GenerateDataForDEF方法将有一个独特的代码,如:

StringBuilder sb = new StringBuilder();
sb.Append("STUDENT_NUMBER");
sb.Append("'tCALLBACK_NUMBER");
sb.Append("'tSPECIALINSTRUCTIONS");
...

这样就可以为一个制表符分隔的文件创建一个标题。然后会有一个for循环,它的代码如下:

foreach (Model model in modelList)
{
string sstudentNumber = "789";
sb.Append("'t");
sb.Append("'t");//SPECIALINSTRUCTIONS
sb.Append("'t" + model.ExamNumber);
...
}

foreach在所有方法中都很常见,唯一的区别是Model对象中使用的属性。因此,一种方法可以使用所有属性,另一种方法可能只使用5。

目前,如开头所述,有单独的方法,并且根据这些方法的要求使用属性。

在我看来,这里有两个问题需要解决:

  1. 每个方法中的自定义部分。如何处理
  2. 前臂。有其他人吗

我尝试将模型所需的属性放入xml中,然后为每个只分配所需属性的方法构建模型。这似乎奏效了,但只解决了难题的一部分。

任何线索或方向都值得赞赏。

谨致问候。

重构问题指导

假设我没有误解整个问题,一个解决方案是使用一个字符串与String.Format():一起使用的单个方法

private string GenerateData(string outputFormat, List modelList, Student student) {
  foreach (Model model in modelList)
  {
    sb.Append(String.Format(outputForm, model.ExamNumber, model.ExamDate, ...);
  }
}

您的具体方法可以重写为:

public string GenerateDataForExamNumber(List modelList, Student student) {
  return GenerateData ("'t'tExam Number: {0}", modelList, student);
}

public string GenerateDataForExamDate(List modelList, Student student) {
  return GenerateData ("'t'tExam Date: {1}", modelList, student);
}

在输出之间需要进一步的微小差异的情况下可能具有额外的CCD_ 2对象。

假设您有一个Heading类,在给定一个字符串的情况下,它返回了适当的标题字符串。

抱歉,这将比C#更像java,但我想你会明白的:

final public static String STUDENT_NUMBER = "Student Number";
final public static String CALLBACK_NUMBER = "Callback Number";
final public static String SPECIAL_INSTRUCTIONS = "Special Instructions";
// etc.
public String getHeading(String key) {
    if (key.equals(STUDENT_NUMBER) return STUDENT_NUMBER;
    // etc;
}

这可以通过使用Map来简化,但它很简单。

现在假设你的模型也可以返回一个给定密钥的字符串:

public String getCell(String key) {
    if (key.equals(STUDENT_NUMBER) return StudentNumber;
    // etc.
}

同样,这是可以改进的,使用一个单独的类来提供单元格值,但这是一个没有真正帮助解释的细节,所以我将把它排除在代码之外。

现在,取一个标题列表或数组:

final String[] columns = {STUDENT_NUMBER, CALLBACK_NUMBER, SPECIAL_INSTRUCTIONS};

并将该列表传递给一种新方法:

public String makeTable(Heading heading, Model[] models, String[] columns) {
    StringBuilder sb = new StringBuilder();
    for (String column: columns) {
        sb.Append(heading.getHeading(column).Append("'t");
    }
    for (Model model: models) {
        for (String column: columns) {
            sb.Append(model.getCell(column).Append("'t");
        }
    }
    return sb.toString();
}

当然,你可以担心后面的标签,但基本上我们已经推广了解决方案。