您如何处理代码中的抽象理解?


15

在查看新的代码库时,我喜欢从下至上的方法开始。
我在其中理解一个文件,然后移至下一个抽象。
但是很多时候我发现自己忘记了底层抽象在做什么。

因此,在这一点上,我发现自己陷入了无尽的循环,回到我以前完全理解的文件,然后尝试重新学习它们。同时尝试弄乱彼此之间相互联系的许多其他抽象。

是否有更好的策略来应对这种情况?

我是否应该忘记较低级别的细节,并将其视为既定知识?但是即使如此,很多时候仍需要对底层抽象有一个先前的了解,以了解当前抽象在做什么。



10
简短的答案:您的起点错误。自上而下的方法总是更有效的,因为随着您降低每个级别,您将了解它的含义,含义。如果从底部开始,您将缺少必要的上下文。这使您难以记住,因为您无法将看到的东西与任何有意义的东西联系起来。首先,只看大图,只有理解了之后,再放大需要/想要了解的细节。
马丁·马特

您不必记住所有的事情。您可以使用纸或iPad绘制简单的图表,以帮助您记住关联和抽象。
sul4bh

Answers:


31

具体来说,编程是将细节拉向您的冲动,因此您可以将所有细节都固定在一个地方。我们都是以这种方式开始的,很难放手。

抽象编程绝对是“忘记了底层细节”。有时甚至是高级细节。您将细节推开,让其他东西处理它们。偷偷摸摸的事情是你一直在这样做。您真的了解这一切之间发生的一切print "Hello world"并在屏幕上显示吗?

当您努力放弃这些细节时,要求的第一件事就是好名字。一个好名字确保您进入内部时不会感到惊讶。这就是为什么您print对在屏幕上放一些东西并不真正在乎,并不感到惊讶。foo "Hello world"会是另外一个故事。

同样,抽象级别应该保持一致。如果您处于计算pi的水平,则也不必担心如何显示pi。该细节泄漏到了一个不属于它的抽象中。

较低,较高或横向的细节,与我在这个地方考虑​​的一件事无关,可以完全消失或至少隐藏在好名字后面。

因此,如果您真的很难从一个文件跳到另一个文件,那么我会赔率某个人用坏名或抽象漏洞将您困住了。

我用手指阅读来解决此问题。一旦围绕这种混乱进行了体面的测试,我就将责任分开,给他们清楚的名字以避免出现意外,并向其他人展示以确保我不生活在幻想世界中。

显然,我并不是一个人这样工作:

每当我处理不熟悉的代码时,我都会开始提取方法。执行此操作时,我会寻找可以命名的代码块-然后将其提取。即使最终内联了以后提取的方法,至少我还是有一种暂时隐藏细节的方法,以便可以看到整体结构。

迈克尔·费瑟斯(Michael Feathers)-橙色代码


12

在底部,每半年左右对我的表现有一些更新,我认为它们很有价值。

好的名字。或者,如果这是其他人的代码,则尝试基于该系统的类/函数上的甚至是坏名字来赋予好名字/职责,因此在我看来很有意义。一旦完成,低级实现就变得更容易记住。

这就是我的全部。这个站点上有许多纯粹主义者,他们会发誓天知道那些什么类型的图案或物体,但是好的命名会让您走得更远。通过创建最少文档化/命名良好/分离度良好的代码,我自己做得还不错,即使很多地方使用了我的代码,很多人也没想到这一点,但是我做对的一件事是浪费大量时间在良好的命名,良好的注释和解释我的代码流程的示意图上。如果您想深入了解我的代码,则必须了解底层实现。可以以合理的方式扩展编写良好的代码,因此,有人或您不了解/记住低级实现也可以。

如果您对我和我原来的领域的人们都知道是事实的争议感兴趣,但是,如果您听了这里写的内容,您将学会同意和不同意此答案,请继续阅读:


但是这里还有另一个问题-纯粹主义者。您会听到措辞合理且完全合乎逻辑的答案和意识形态,实际上,它们没有错。但是您不必遵循它们,实际上,它们可能会加剧您的劣势。

我的朋友们在大型系统上工作,他们只是嘲笑那些过于关注约定和模式的人,并且出于充分的理由,我也愿意这么做-我可以从我的数据分析的主要领域中找到我这样做的理由,因为我不是一个经验丰富的开发人员,所以您认为大多数事情都很重要,无所谓,从这个意义上说,您的自我与您有很强的联系。通常,一个人由于自己的自我而会知道,由于他的偏见,他很可能会误解了这种偏见。如今,这种偏见被一个他认为只是说“我做过的同样的事情”的权威所强化。这是一个众所周知的陷阱,您永远都不会陷入。这并不意味着他没有正确地使用它或为了更大的利益而使用它,但是通常,这些人会做的是保证他们所说的都是金奖。

所以,你可以做什么?

向同事解释您的代码,并从高层的角度询问他们是否有意义。

就是这么重要。当然,正在阅读别人代码的任何人都将始终有一个alt选项卡节来查看某些事物的实现,但这无关紧要,如果正在阅读您的代码的人对您的系统有较高的了解并理解“为什么会发生”(再次,不必完全知道“它们如何发生”),那么您就很厉害。

这不是我要说的继续编写不高性能或不尊重任何内容的废话代码,而是要说的是:

1)可以忘记。随着时间的流逝,您将在阅读正在使用的代码方面变得更好。如果您正在阅读的代码要求您精通底层的实现,那么它的代码编写错误,并且会影响到我之前所说的内容:同事是否理解您?

2)世界上充满了很多非常聪明的人,他们不是很聪明。他们有时也常常情绪激动,容易受到外界力量的偏见。他们非常擅长做事,但是作为传播信息的参与者,他们忘记的是:想法/信息,即使有“逻辑”的支持,也具有发送这些信息的上下文,这对于理解是否做到这一点至关重要。信息对您也很有用。对您来说有意义的事情可能对其他人也有意义,他们会喜欢的,但是信息不应该被视为绝对信息,应该再次考虑,或者至少尝试弄清信息的来源并检查他的信息。自己的上下文,看看是否匹配。确实与亿万富翁为我们提供了这些“知识点,以取得成功”一样

简而言之:编写可理解的代码,并意识到在我们需要某些人说的尽可能多的模式/类和精炼程序的地方,它仍然是有争议的。论点的两边都有非常聪明的人,它只应该加强以合理的方式为您的团队做任何事情的想法-不要被无关紧要的小细节所困扰,您会想出办法稍后,请记住,您生活在竞争激烈的世界中,时间是最重要的事情:

初创公司的时机成功。

以一种有意义的,贪婪的方式分配您的时间和资源。


这是六个月后的修改:

这是一个疯狂的旅程。我从没想过,仅仅分离/良好的命名和文档功能基本上就可以让您在代码库中插入和插入任何内容。我不得不重新编写大量代码以使其适应新的更改,并且在2-3天内做了很多工作。我可以肯定地说,由于缺乏知识或最佳实践,我没有在任何地方都遵循SOLID,我可以说它们属于我的技术债务,但并不是很多。分开,命名和记录,当您最终意识到自己是多么愚蠢时,它可以让您立即更改代码。

别误会我:如果您编写紧密耦合的代码,无论您是否讨厌SOLID,都会感到很痛苦,即使是在基础级别理解并应用它也可以实现很好的去耦,老实说, OOP真正帮助的唯一一件事。OOP还应该与代码重用有关,而这种情况到处都是,您实际上并不会重复使用创建的许多对象,因此,请集中精力确保系统之间的分隔良好。一旦成熟,让我们假设Bob叔叔来接手并领导了项目,他会说:“好吧,这真是愚蠢,但是至少所有内容都是分开的,有名有据的,所以至少我知道这是怎么回事“ (我希望)。对我来说,它有效。我的LOC一直在变化,但是在撰写本文时,只有11万行代码和11万行执行代码可以使一个人和谐地工作。


这是3个月后对我正在重构的8个月代码的编辑:

这一切都说得通。现在,我可以从概念上重新使用我当时写的内容,并以新的思路重新构建代码,因为我完全了解发生了什么,以及由于原理图/良好的命名和注释,它为什么起作用。很久以前,我写了一些代码,我不太在乎命名的好坏,这很难完成。我现在正在考虑下一步要解释我的代码。


好的名字。最重要的一点。对大多数人而言,这很容易做到,这使事情变得容易得多。
gnasher729
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.