多年来,我听到了大量关于我们开发人员必须使用的继承项目的抱怨。WTF 网站有大量的代码示例,让我忍不住喃喃自语“WTF?”
但是你们中的任何人是否真的被呈现给你的代码,“天哪,这是经过深思熟虑的!” 或“哇,我从来没想过!”
您必须使用哪些继承代码让您微笑,为什么?
多年来,我听到了大量关于我们开发人员必须使用的继承项目的抱怨。WTF 网站有大量的代码示例,让我忍不住喃喃自语“WTF?”
但是你们中的任何人是否真的被呈现给你的代码,“天哪,这是经过深思熟虑的!” 或“哇,我从来没想过!”
您必须使用哪些继承代码让您微笑,为什么?
很久以前,我负责 Turbo C/C++ 运行时库。Tanj Bennett 用 16 位汇编器编写了最初的 80x87 浮点仿真器。我没有仔细查看 Tanj 的代码,因为它运行良好并且不需要关注。但是我们正在转向 32 位,而扩展模拟器的任务落到了我的肩上。
如果可以说编程与艺术有共同之处,那就是它了。
Tanj 的核心数学函数设法将 80 位浮点临时结果保存在五个 16 位寄存器中,而无需从内存中保存和恢复它们。X86 汇编程序员会明白这是何等的成就。寄存器空间稀缺,在进行复杂数学运算的同时保留五个寄存器作为您的临时工是一个值得一看的美丽网站。
如果这只是一个聪明的编码问题就足以将其定性为艺术,但它不仅如此。Tanj 仔细挑选了最适合将温度保存在寄存器中的底层数学算法。结果是一个超快的浮点仿真器,这对我们的许多客户来说是一个重要的卖点。
到 386 出现时,大多数关心浮点性能的人都没有使用仿真器,但我们必须支持 Intel 的 386SX,因此仿真器需要大修。我重写了指令解码逻辑和异常处理,但核心数学函数完全保持不变。
最让我印象深刻并且我试图模仿的代码是看起来太简单易懂的代码。
写这样的代码真是太难了。:-)
在我的第一份工作中,我惊讶地发现代码库 (c++) 中有一个“安全 ID”类,该类将数字 ID 包装在一个以空标记类为模板的类中,以确保编译器在你尝试时会抱怨例如将 UserId 比较或分配给 OrderId。
我不仅确保在我将使用的所有后续代码库中都有一个等效的 Id 类,而且它实际上让我看到了编译器可以做些什么来保证正确性并帮助编写更强大的代码。
我在这里有一个有趣的故事要讲。
我正在开发这个 Javaish 应用程序,里面装满了 getter 和 setter,它们除了 get 或 set 和接口之外什么都不做,而且发明了一切使代码不可读的东西。有一天,我偶然发现了一些看起来制作精良的代码——它基本上是一个看起来非常优雅的算法实现 = 几行可读代码,尽管它尊重项目必须遵守的每一个可能的规则(它是自动检查样式的) .
我无法弄清楚团队中的哪些人可以编写这样的代码。我很想和他讨论并分享想法。值得庆幸的是,几个月前我们已经切换到颠覆(从 cvs),我很快就运行了 am 'svn blame'。我到处闲逛,在实现旁边看到我的名字。
我听说过人们不记得他们 6 个月前编写的代码的故事,维护代码是一场噩梦。我不敢相信会发生这样的事情:你怎么会忘记你写的代码?好吧,现在我确信它会发生。谢天谢地,代码很好并且易于扩展,所以我只经历了一半的故事。
我遇到了我公司另一位程序员的一些 VB6 代码,它们很好地处理了错误情况(无论是直接处理它们还是记录它们)。
以及一些相当复杂的代码,这些代码得到了很好的注释。
我知道这会带来很多答案,例如,
“在我介入之前,我从来没有找到好的代码”和变体。
我认为真正的问题不在于没有优秀的编码人员或优秀的项目,而是存在过多的NIH综合症以及没有人喜欢其他人的代码这一事实。后者只是因为你必须付出智力来理解它,这比你需要理解自己的代码要付出更大的努力,所以你不喜欢它(它让你思考和工作)。
就我个人而言,我记得(我猜每个人都记得)一些非常糟糕的代码案例,但我也记得一些记录良好、优雅的代码。
目前,给我印象最深的项目是一个非常强大的动态工作流引擎,不仅因为它的简单性,还因为它的编码方式。我可以在这里和那里记住一些非常聪明的片段,以及一个漂亮的元编程库,它基于我的一些朋友开发的完整 IDL ( Aspl.es )
我继承了一大堆写得很好的代码,我实际上花了 40 美元在网上找到了那个人,我去他家感谢了他。
我认为 Rocky Lhotka 应该得到赞扬,但我最近不得不接触一个 CSLA.NET 应用程序{在我的私人实践中},我对代码的有序性印象深刻。该应用程序运行得非常好,但客户需要一些扩展。原作者惨死,新人不老实。他不了解 CSLA.NET 的基于业务对象的方法,他想在没有任何花哨的框架的情况下,用干巴巴的 VB.NET 重新做一遍。
于是我接到了电话。看一个 WinForm 绑定和 CSLA.NET 的工作示例对很多事情很有启发性。
Symbian OS - 无论如何,它的旧核心部分,可以追溯到 Psion 时代的部分,或者即使在今天仍然保持这种精神的人。
坐在它旁边,到处都是大电话公司雇用的最低价者创造的所有新垃圾。令人吃惊的是,您实际上可以从骨子里感觉到代码库是旧的还是新的。
我记得当我写关于类型推断的学士论文时,我的 Pascal-to-Pascal “编译器”是我的主管(用 Java)编写的 Parser 的扩展。据我所知,它的结构非常好,对于从未做过任何严肃的面向对象编程的我来说,这是一个相当大的启示。
我一直在进行大量的 Eclipse 插件开发,并且经常不得不调试到实际的 Eclipse 源代码中。虽然我没有“继承”它,因为我不会继续研究它,但我一直对早期核心的设计和质量印象深刻。