1

我目前正在从事一项大学作业,我知道设计对评分标准至关重要。

目标是基本上读取一个文本文件并返回每个单词出现的计数。有一些小的要求,包括实现一个二叉树(类词,它有一个词的字符串和它的出现次数)和对文本文件中的总词数进行计数。

当我填满树的时候,我可以记录我读过的字数。我的方法 fillTree 可以返回文件中的单词数,而不必再次遍历它,但显然方法名称与它根本不相关,我们被告知一个方法应该只做一件事。将这两个过程分开还是保持原样更好?还是我需要重新考虑我的整个方法?

请耐心等待,因为这是我在 SO 上的第一个问题。谢谢!

4

5 回答 5

2

优雅和性能之间经常存在张力。

假设您有一个函数std::map<std::string, size_t> computeStatistics(std::istream& input)可以解析输入流并计算每个单词的出现次数,并将它们存储到map.

然后你可以实现:

  • size_t countOccurrencesOfWord(std::string const& word, std::istream& input),作为解析然后查找地图。
  • size_t countWords(std::istream& input),作为解析然后总结计数。

每个方法都有一个单一的职责,但是有很多重复的工作。我建议改为公开中间步骤:

class FileStatistics;

FileStatistics computeStatistics(std::istream& input);

这个类可以公开简单的方法:

size_t FileStatistics::getOccurrencesOfWord(std::string const& word) const;
size_t FileStatistics::getTotalNumberOfWords() const;

在内部,您可以选择其结构。我的建议是std::map<std::string, size_t>针对事件的一个,而只是size_t针对总数的一个。

于 2013-05-16T08:41:27.127 回答
0

从长远来看,命名两个单独的方法对于代码维护会更好。如果将来有人必须在您不在的情况下进行此项目,则唯一的名称和功能将帮助他更轻松地理解和调试。这就是为什么建议使用一种方法只做一件事并且方法名称应该能够让开发人员了解它的实际作用。

于 2013-05-16T05:06:22.797 回答
0

我们被教导说一个方法应该只做一件事

差不多。不幸的是,程序比这更复杂。如果你把这个想法发挥到极致,方法将没有参数;)所以在编写接口和编写程序时,你需要考虑便利性和可用性。这需要考虑,但是您拥有的经验越多,就越容易理解您正在解决的问题,以及任何客户将如何使用该界面。

在这种情况下,字数和单独的字数是完全不同的。考虑一下:如何将它参数化为一种方法?您应该使用什么特殊的奇怪限定词来表示“所有单词”?NULL或者空字符串将是 C 接口中的常见选择,甚至在某些 C++ 接口中也是如此。但是,我不认为这是一个设计良好的界面(有些人会不同意)。

IMO,理想的接口将有两种不同的方法:

size_t wordCount() const;
size_t countOccurrencesOfWord(const std::string& pWord) const;

而我之前劝阻的界面是:

// eah, just pass NULL or an empty string for the word count of the text file
size_t countOccurrencesOfWord(const std::string* const pWord) const;

但是,另一个考虑因素是公共接口与私有接口。你的公共接口可能提供了 2 种方法,但是如果内部实现在某些情况下可能会选择相同的底层实现,或者在问题相似时会略有不同。假设您的类包装了一个 C 接口,该接口具有size_t SomeTypeCountOccurrencesOfWord(SomeTypePtr pSomeType, const char* const pWord);允许NULL参数的接口pWord——那么两个单独的方法仍然是一个不错的选择,即使它们的底层实现几乎相同。

我最初采取的方法是首先填充树,然后提供必要的接口来计算一个单词或所有单词。然后,如果我确定缓存一个值是一个好主意,我可以很容易地在事后引入一个变量。

于 2013-05-16T05:09:23.460 回答
0

我建议你想问fillTree应该是什么返回值。很可能是成功代码。

您是否需要跟踪元素计数?如果是这样,我会认为将其直接存储在数据结构中是可行的。

话虽如此,如果它使代码更简单易读fillTreeAndReturnElementsStored当然不是不合理的做法。

于 2013-05-16T05:14:32.913 回答
0

坚持单一职责原则(一个类或方法应该只做一件事和一件事)。拥有其他人建议的两种方法将是更好的设计。

许多软件项目的主要问题之一是它们不仅违反了单一责任原则,而且这样做最终违反了开放封闭原则

于 2013-05-16T05:15:35.663 回答