如何识别代码是否过度抽象?
应该使用哪些措施来识别代码是否过度抽象且很难理解以及应该采取哪些措施来减少过度抽象?
What should be the measures that should be used to identify that code is over abstracted and very hard to understand and what should be done to reduce over abstraction?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
“简单性胜过复杂性,复杂性胜过复杂性”
因此,只有当您将复杂性“去层次”化为复杂性时,抽象某些东西才有好处。这样做的原因可能有所不同:更好的模块化、更好的封装等。
识别过度抽象是先有鸡还是先有蛋的问题。为了减少过度抽象,您需要了解代码行背后的实际原因。这包括理解特定抽象本身的想法(与由于缺乏理解而将其称为抽象原因相反)。但这还不够——您需要知道一个更好、更简单的解决方案来证明它过于抽象。
如果您正在寻找可以代替您完成此任务的工具 - 无需再寻找,只有头脑才能可靠地判断。
"Simplicity over complexity, complexity over complicatedness"
So - there's a benefit to abstract something only if You are "de-leveling" complicatedness to complexity. Reasons to do that can vary: better modularity, better encapsulation etc.
Identifying over abstraction is a chicken and egg problem. In order to reduce over abstraction You need to understand actual reason behind code lines. That includes understanding idea of particular abstraction itself (in contrast to calling it over abstracted cause of lack of understanding). And that's not enough - You need to know a better, simpler solution to prove that it's over abstracted.
If You are looking for tool that could do it in Your place - look no more, only mind can reliably judge that.
我将给出一个会得到很多反对票的答案!
如果代码是用面向对象语言编写的..它必然是严重过度抽象的。语言越纯粹,问题就越严重。
应该非常谨慎地使用抽象。如果有疑问,请始终使用具体的数据结构。 (您可以稍后进行抽象,这比去抽象更容易:)
您必须非常确定在当前上下文中拥有正确的抽象,并且您必须非常确定该概念能够经受住变化的考验。抽象对代码和编码器的性能都有很高的代价。
对过度抽象的一些弱测试:如果数据结构是产品类型(C 中的结构)并且程序员为每个字段编写了 get 和 set 方法,那么他们完全无法提供任何真正的抽象,禁用像 C 增量这样的运算符,没有任何目的,并且根本不理解结构体字段名称已经是产品的抽象表示。复制和修补界面并不是一个好主意。
对产品案例的一个很好的测试是是否存在需要维护的数据不变量。例如,表示有理数的一对整数几乎就足够了,几乎不需要任何抽象,因为除非分母为零,否则所有对都是有效的。然而,出于性能原因,人们可能会选择保持不变量,通常要求分母大于零,并且分子和分母互质。为了确保不变性,封装了乘积表示:由构造函数保护的初始值和受约束以维持不变性的方法。
要修复代码,我建议执行以下步骤:
记录抽象所维护的表示不变量
如果找不到强不变量,则删除抽象(方法)
p>
使用直接访问数据的方法重写代码。
此过程仅适用于低级抽象,即按类对小值进行抽象。
更高层次上的过度抽象更难处理。理想情况下,您应该重复重构代码,在每个步骤之后检查它是否继续工作。然而这会很困难,有时需要进行重大重写,而不是改进。除非抽象离基础太远以至于无法继续维护它,否则这可能不值得。
I will give an answer that will get a LOT of down votes!
If the code is written in an OO language .. it is necessarily heavily over-abstracted. The purer the language the worse the problem.
Abstraction should be used with great caution. If in doubt always use concrete data structures. (You can always abstract later, this is easier than de-abstraction :)
You must be very certain you have the right abstraction in your current context, and you must be very sure that concept will stand the test of change. Abstraction has a high price in performance of both the code and the coder.
Some weak tests for over-abstraction: if the data structure is a product type (struct in C) and the programmer has written get and set method for each field, they have utterly failed to provide any real abstraction, disabled operators like C increment, for no purpose, and simply not understood that the struct field names are already the abstract representation of a product. Duplicating and laming up the interface is not a good idea.
A good test for the product case is whether there exist any data invariants to maintain. For example a pair of integers representing a rational number is almost sufficient, there's little need for any abstraction because all pairs are valid except when the denominator is zero. However for performance reasons one may choose to maintain an invariant, typically the denominator is required to be greater than zero, and the numerator and denominator are relatively prime. To ensure the invariant, the product representation is encapsulated: the initial value protected by a constructor and methods constrained to maintain the invariant.
To fix code I recommend these steps:
Document the representation invariants the abstraction is maintaining
Remove the abstraction (methods) if you can't find strong invariants
Rewrite code using the method to access the data directly.
This procedure only works for low level abstraction, i.e. abstraction of small values by classes.
Over abstraction at a higher level is much harder to deal with. Ideally you'd refactor the code repeatedly, checking to see after each step it continues to work. However this will be hard, and sometimes a major rewrite is required, rather than a refinement. It's probably not worth it unless the abstraction is so far off base it is not tenable to continue to maintain it.
下载 Magento 并查看代码,阅读一些相关文档并查看其 ERD:http://www.magentocommerce.com/wiki/_media/doc/magento---sample_database_diagram.png?cache=cache
我不是在开玩笑,这过于抽象..试图取悦每个人并覆盖每个基础是一个糟糕的主意,并且使每个人的生活变得极其困难。
Download Magento and have a look at the code, read some documents on it and have a look at their ERD: http://www.magentocommerce.com/wiki/_media/doc/magento---sample_database_diagram.png?cache=cache
I'm not joking, this is over-abstraction.. trying to please everyone and cover every base is a terrible idea and makes life extremely difficult for everyone.
我完全同意 @ArnisLapsa 所写的:
而且
(从复杂到简单)
另外,正如 @MartinHemmings 一个好的抽象是相当主观的,因为我们的想法并不相同。事实上,我们的思维方式会随着时间而改变。因此,一些人觉得简单的事情在其他人看来可能很复杂,甚至随着经验的增加而变得更简单。例如。一元操作对于函数式程序员来说是微不足道的,但对其他人来说却可能会造成严重的困惑。同样,可变对象相互通信的设计对于某些人来说可能很自然,而对于其他人来说则感觉难以追踪。
话虽这么说,我想添加几个指标。请注意,这适用于代码库中使用的抽象,而不是“范式抽象”,例如一切都是函数或一切都设计为对象。因此:
I completely agree with what @ArnisLapsa wrote:
And that
(and from complex to simpler)
Also, as stated by @MartinHemmings a good abstraction is quite subjective because we don't all think the same way. And actually our way of thinking change with time. So Something that someone find simple might looks complex to others, and even become simpler with more experiences. Eg. A monadic operation is something trivial for functional programmer, but can be seriously confusing for others. Similarly, a design with mutable object communicating with each other can be natural for some and feel un-trackable for others.
That being said, I would like to add a couple of indicators. Note that this applies to abstractions used in code-base, not "paradigm abstraction" such as everything-is-a-function, or everything-is-designed-as-objects. So:
我个人会说“理想的抽象级别是什么?”是一个主观问题。
我不喜欢为每个原子操作使用新行的代码,但我也不喜欢一行内有 10 个嵌套操作。
我喜欢使用递归函数,但我不喜欢仅仅为了递归而递归。
我喜欢泛型,但我不喜欢(嵌套)泛型函数,例如,对于预期的每种特定类型使用不同的代码......
这是个人观点和常识的问题。这能回答你的问题吗?
Personally I would say that "What is the ideal level of abstraction?" is a subjective question.
I don't like code that uses a new line for every atomic operation, but I also don't like 10 nested operations within one line.
I like the use of recursive functions, but I don't appreciate recursion for the sole sake of recursion.
I like generics, but I don't like (nested) generic functions that e.g. use different code for each specific type that's expected...
It is a matter of personal opinion as well as common sense. Does this answer your question?