如何识别代码过度抽象?

时间:2010-09-15 07:47:44

标签: abstraction

应该使用哪些措施来确定代码是否过度抽象且非常难以理解以及应该采取哪些措施来减少过度抽象?

5 个答案:

答案 0 :(得分:12)

我会给出一个会得到很多票数的答案!

如果代码是用OO语言编写的话,则必然会过度抽象。语言越纯,问题越严重。

应该非常谨慎地使用抽象。如果有疑问,总是使用具体的数据结构。 (你可以随后抽象,这比去抽象更容易:)

你必须非常肯定你在当前的背景下有正确的抽象,你必须非常肯定这个概念将经得起变革的考验。抽象在代码和编码器的性能上都有很高的代价。

过度抽象的一些弱测试:如果数据结构是产品类型(C中的结构)并且程序员为每个字段编写了get和set方法,那么它们完全无法提供任何真正的抽象,像C增加,没有任何意义,并且根本不理解struct字段名称已经是产品的抽象表示。复制和编写界面并不是一个好主意。

对产品案例的一个很好的测试是,是否存在任何要维护的数据不变量。例如,表示有理数的一对整数几乎就足够了,几乎不需要任何抽象,因为除了分母为零之外,所有对都是有效的。然而,出于性能原因,可以选择保持不变量,通常分母要求大于零,并且分子和分母是相对素数。为了确保不变量,产品表示被封装:由构造函数保护的初始值和约束维护不变量的方法。

要修复代码,我建议您执行以下步骤:

  1. 记录抽象维护的表示不变量

  2. 如果找不到强不变量,请删除抽象(方法)

  3. 使用该方法直接访问数据重写代码。

  4. 此过程仅适用于低级抽象,即按类抽象小值。

    更高层次的过度抽象更难处理。理想情况下,您将重复重构代码,检查每个步骤后是否继续工作。然而,这将很难,有时需要重大改写,而不是改进。它可能不值得,除非抽象远离基础,否则不能继续维持它。

答案 1 :(得分:11)

“简单复杂,复杂而非复杂”

所以 - 只有当你“复杂化”复杂性的复杂性时,抽象的东西才有好处。这样做的原因可能有所不同:更好的模块化,更好的封装等。

识别过度抽象是鸡和蛋的问题。为了减少过度抽象,您需要了解代码行背后的实际原因。这包括理解特定抽象本身的想法(与将其称为缺乏理解的抽象原因相反)。这还不够 - 你需要知道一个更好,更简单的解决方案来证明它已经过度抽象了。

如果您正在寻找可以在您的位置执行此操作的工具 - 请不要再看,只有大脑能够可靠地判断它。

答案 2 :(得分:2)

下载Magento并查看代码,阅读其中的一些文档并查看其ERD:http://www.magentocommerce.com/wiki/_media/doc/magento---sample_database_diagram.png?cache=cache

我不是在开玩笑,这是过度抽象的...试图取悦每个人并覆盖每一个基地是一个可怕的想法,让每个人的生活变得非常困难。

答案 3 :(得分:1)

我个人会说“理想的抽象级别是什么?”是一个主观问题。

我不喜欢为每个原子操作使用新行的代码,但我也不喜欢一行中的10个嵌套操作。

我喜欢使用递归函数,但我不赞赏递归只是为了递归。

我喜欢泛型,但我不喜欢(嵌套)泛型函数,例如为预期的每种特定类型使用不同的代码......

这是个人意见和常识的问题。这是否回答了你的问题?

答案 4 :(得分:0)

我完全同意@ArnisLapsa的写道:

"Simplicity over complexity, complexity over complicatedness"

an abstraction is used to "de-level" those, from complicated to complex

(从复杂到简单)

而且,正如@MartinHemmings所述,好的抽象是非常主观的,因为我们的想法并不相同。实际上,我们的思维方式会随着时间而改变。因此,某人发现简单的事物可能对其他人看起来很复杂,甚至随着更多的经验变得更简单。例如。对函数式程序员而言,单子操作是微不足道的,但对于其他程序员却可能造成严重的混淆。类似地,具有可变对象相互通信的设计对于某些人而言可能是自然的,而对于其他人而言则感觉无法追踪。

话虽如此,我想补充一些指标。请注意,这适用于代码库中使用的抽象,而不适用于“范式抽象”,例如“一切都是功能”或“一切都是设计为对象”。所以:

  • 对它关注的人,抽象应该比其他选择在概念上更简单,而无需查看实现。如果您发现考虑所有可能的情况比使用抽象推理更简单,则此抽象不适合您(
  • 其实现应仅考虑抽象,而不是将用于的特定情况。一旦抽象实现包含针对特定情况的部分,就表示“不合适”抽象。为了应对每种新情况而增加的概括性是错误的方法(并且倾向于落入下一个问题)。
  • 我发现(实际上是因为)过度抽象的一个非常普遍的指示是抽象,它代表的是比现在还需要的更多的东西。他们应该尽可能地允许他们做所需的事情,但仅此而已。例如,假设您正在考虑或已经具有“二维点”抽象,可以为该抽象定义所需的许多运算符。然后,您还有另一个需求,它实际上可能是类似于2d的“ 4d点”。不要开始使用“ Ndimensionnal点”抽象,尤其要考虑到以后可能需要它。也许除了2d和4d之外,别无其他(因为它永远都是积压的“好主意”),但是有些要求突然出现,将4d点转换为成对的2d点。很难将其推广到n维。因此,可以检查每个抽象以覆盖,而仅覆盖实际需求。在我的例子中,复杂度“ n维”实际上仅用于处理2d和4d情况(而4d甚至可能用不了那么多)。
  • 最后,从更全球化的角度来看,具有许多不相关抽象的代码库表明开发团队倾向于抽象每个小问题。因此,其中许多人可能已经或变得过于抽象。