满足 Martin 的简洁代码功能标准的程序结构

Program Structure to meet Martin's Clean Code Function Criteria

我一直在阅读 Clean Code by Robert C. Martin 并且有一个关于函数和程序结构的基本(但基本)问题。

书中强调函数应该:

  1. 要简短(如 10 行或更少)
  2. 只做一件事

我不太清楚如何在实践中应用它。例如,我正在开发一个程序来:

  1. 加载基线文本文件
  2. 解析基线文本文件
  3. 加载测试文本文件
  4. 解析测试文本文件
  5. 将解析的测试与解析的基线进行比较
  6. 汇总结果

我尝试了两种方法,但似乎都不符合 Martin 的标准:

方法 1

设置一个 Main 函数来集中控制工作流中的其他函数。但是 main() 最终可能会变得很长(违反#1),并且显然会做很多事情(违反#2)。像这样:

main()
{
    // manage steps, one at a time, from start to finish
    baseFile = loadFile("baseline.txt");
    parsedBaseline = parseFile(baseFile);
    testFile = loadFile("test.txt");
    parsedTest = parseFile(testFile);
    comparisonResults = compareFiles(parsedBaseline, parsedTest);
    aggregateResults(comparisonResults);
}

方法 2

使用 Main 触发函数 "cascade"。但是每个函数都在调用一个依赖项,所以它们似乎仍然在做不止一件事(违反#2?)。例如,内部调用聚合函数需要进行结果比较。流程似乎也是倒退的,因为它从最终目标开始,并在进行过程中调用依赖项。像这样:

main()
{
    // trigger end result, and let functions internally manage
    aggregateResults("baseline.txt", "comparison.txt");
}

aggregateResults(baseFile, testFile)
{
    comparisonResults = compareFiles(baseFile, testFile);   

    // aggregate results here
    return theAggregatedResult;
}

compareFiles(baseFile, testFile)
{
    parsedBase = parseFile(baseFile);
    parsedTest = parseFile(testFile);

    // compare parsed files here        
    return theFileComparison;
}

parseFile(filename)
{
    loadFile(filename);

    // parse the file here
    return theParsedFile;
}

loadFile(filename)
{
    //load the file here
    return theLoadedFile;
}

显然函数需要相互调用。那么,构建满足 Martin 标准的程序的正确方法是什么?

我认为您没有考虑上下文,对规则 2 的解释是错误的。 main() 函数只做一件事,那就是 一切 ,即 运行 整个程序。假设你有一个 convert_abc_file_xyz_file(source_filename, target_filename) 那么这个函数应该只做它的名字(和参数)所暗示的一件事:将格式 abc 的文件转换为格式 xyz。当然,在较低的层次上,要实现这一点还有很多事情要做。例如读取源文件(read_abc_file(…)),将数据从格式abc转换为格式xyzconvert_abc_to_xyz(…)),然后将转换后的数据写入新文件(write_xyz_file(…))。

第二种方法是错误的,因为编写只做一件事的函数变得不可能,因为每个函数都在“级联”调用中做所有其他事情。在第一种方法中,可以测试或重用单个函数,即只需调用 read_abc_file() 来读取文件。如果该函数调用 convert_abc_to_xyz(),而后者又调用 write_xyz_file(),那就不可能了。