单一责任原则基于高度凝聚力原则。两者之间的区别在于,具有高度凝聚力的班级具有一系列密切相关的职责,而遵守SRP的班级仅具有一个职责。
但是,我们如何确定某个特定类别是否具有一组职责并因此具有高度凝聚力,或者它是否仅具有一项职责并因此遵守SRP?换句话说,是不是有些主观,因为有些人可能认为一类非常细化(因此相信该类遵循SRP),而另一些人可能认为它不够细密?
单一责任原则基于高度凝聚力原则。两者之间的区别在于,具有高度凝聚力的班级具有一系列密切相关的职责,而遵守SRP的班级仅具有一个职责。
但是,我们如何确定某个特定类别是否具有一组职责并因此具有高度凝聚力,或者它是否仅具有一项职责并因此遵守SRP?换句话说,是不是有些主观,因为有些人可能认为一类非常细化(因此相信该类遵循SRP),而另一些人可能认为它不够细密?
Answers:
为什么是的,这是非常主观的,并且它是程序员参与的许多激烈的,红脸辩论的主题。
确实没有一个答案,而且随着软件变得越来越复杂,答案可能会改变。曾经是一个定义明确的任务,最终可能会变成多个定义不明确的任务。这总是很麻烦。您如何选择将程序划分为任务的正确方法?
关于我唯一可以提供的建议是:运用您(和您的同事)的最佳判断。请记住,如果您尽快发现错误,通常可以纠正这些错误。
我可以给你一些经验法则。
单一责任原则指出,每个软件模块都只有一个更改理由。在鲍勃叔叔最近的一篇文章中,他解释了“改变的理由”,
但是,在考虑这一原则时,请记住,改变的原因是人。是要求更改的人。而且,您不希望通过将许多不同人出于不同原因而关心的代码混合在一起来混淆这些人或您自己。
他用一个例子在这里进一步解释了这个概念。
要回答这个问题,请退后一步,考虑一下单一责任原则的意图。为什么首先将其推荐为设计原则?
该原理的目的是“分隔”代码库,因此与单个“职责”相关的代码被隔离在单个单元中。这使查找和理解代码变得更加容易,更重要的是,这意味着对“责任”的更改将只影响单个代码单元。
您绝对不希望在系统中发生的情况是,当一个很小的机会导致代码中其他显然无关的部分失败或改变行为时。SRP有助于隔离错误和更改。
那么,这是什么“责任”呢?可以想象,它可以独立于其他更改而更改。假设您有一个程序可以将一些设置保存到XML配置文件中,并且可以从文件中读回它们。这是单一职责,还是“加载”和“保存”两个不同的职责?对文件格式或结构的任何类型的更改都需要更改加载和保存逻辑。因此,这是一种责任,应该由一个班级来代表。现在考虑一个可以导出CVS,Excel和XML格式的数据的应用程序。在这种情况下,很容易想到一种格式可以更改而不会影响另一种格式。如果您决定以CVS格式更改定界符,则它不应影响Excel输出。
只是为了讨论起见,我将从JUCE 调出一个名为AudioSampleBuffer的类。现在,该类可以保存一小段音频(或相当长的一小段音频)。它知道通道数量,样本数量(每个通道)似乎是致力于32位IEEE浮点数的,而不是具有可变的数字表示形式或字长(但这对我来说不是问题)。有一些成员函数可让您获取numChannels或numSamples以及指向任何特定通道的指针。您可以使AudioSampleBuffer更长或更短。我假设前者对缓冲区进行零填充,而后者则被截断。
此类的一些私有成员用于在JUCE使用的特殊堆中分配空间。
但这就是AudioSampleBuffer所缺少的(我已经与Jules进行过多次讨论):名为的成员SampleRate
。 怎么会错过呢?
AudioSampleBuffer需要履行的唯一职责是充分代表人们听到其样本所代表的物理音频。当您从读取声音文件的内容或流中输入AudioSampleBuffer时,必须获取一个附加参数,并将其与AudioSampleBuffer一起传递给需要知道采样率的处理方法(例如,它是一个滤波器),或者最终,找到了一种方法来播放缓冲区(或将其传输到其他地方)。随你。
但是,您要做的就是继续传递此SampleRate,它是AudioSampleBuffer中特定音频固有的,并传递到任何地方。我看过将常量 44100.0f传递给函数的代码,因为程序员似乎不知道该怎么做。
这是一个未能履行其单一责任的例子。