代码自注释越充分,其他人就更可能按照其初始的意图来实现它,代码也会有更好的质量。记住,在计算机科学中只有两类问题最难:缓存失效、命名和off-by-one错误。(我怀疑作者是写错了,这是三个…)。 “如果你想成为一个伟大的开发者,请确保你写的代码让人见名知意:也就是说代码精确地完成了它名字告诉的东西” http://t.co/6JMyGvGuzl — Peter Nixey (@peternixey) April 22, 2014 在学习广泛之前先精深某一方面——从里到外学习你选择的技术栈。只有非常少的编程问题是真正新的。很多公司所做的技术工作,是之前的许多团队已做过的。在Stack Overflow上吸引眼球的问题很少没有在其他地方遇到过。 因为这个确切的原因,你正在努力做的大部分事情,已经被你当前使用的技术栈解决过了。我有一次使用了Rails自带的简单而强大的方法,将其他人写的60多行Rails代码重构为一行语句, 大多数程序浪费了大量的时间,用于重新实现那些现有的功能。http://t.co/6JMyGvGuzl — Peter Nixey (@peternixey) April 22, 2014 这不仅浪费了他们的时间,而且他们新构建的代码冗长且含有很多错误。新的代码需要新的文档注释,新的测试来检查,也让代码充满噪杂,并且难以阅读。和其他新代码一样,也容易产生bug。使用技术栈经过严谨测试并且实际验证的代码,很少产生bug。 如果你是一个Ruby的开发者,请花时间好好学习Ruby,尤其是数组的那些惊人多的方法。如果你是Node的开发者,请花时间了解它的架构、方法及理念体系。如果你是一名Angular的开发者,你应该敢于挑战,并理解正由核心团队锤炼的那不可思议的架构背后的逻辑。在你重新发明之前先询问。你行走在巨人的阴影下,花费一些时间找到他们的踪迹,然后你会对他们已经建立的东西感到惊叹。因为,如果你不这样做,你只是把问题推给了后面的人,别人会指出为什么你偏偏选择了你自己的小路走。
学会辨识糟糕的代码有时候,我注意到一些程序员挺不错的,只不过他们趋于安逸,并没有意识到他们的代码其实可以写得更好。这对于你个人的发展是一件极为糟糕的事情,在你知道如何改进之前,先要知道什么是需要改进的。知道好的代码应该是怎么样的,坏的代码长得怎么样。据说,象棋大师比普通棋手花费多得多的时间,来学习其他优秀棋手的如何下棋。我非常确信这对于开发者来说也是对的。 能觉察到代码异味,是提升你能力的重要的武器之一——哪怕只是有一点点异味或者闻起来可能有点异味。异味代码,你可能不知道为什么,仅仅是觉得哪里不对的代码。 你可能做某件事情用了60行代码感觉这很简单,这也可能让你觉得应该交由语言本身来处理却被程序员手动处理了的感觉,也可能是你觉得这段代码糟糕透顶且难以阅读。这就是代码异味。 这不是件容易的事情,但是经过一些年,你会发现哪些代码存在异味,漂亮的代码应该是怎么样的。你会开发出对代码的审美观,对于丑陋事物所带有的丑陋理论会让你感觉很不舒服。简单即是美,而简单正是我们所需要的。 真理是,真实有时候是丑陋的,但是你应该不断地追求美丽,并且当你感觉丑陋无法避免,你知道如何优雅地展示它。如果你不能编写出优雅的代码,最少创建一个史莱克式的代码,而在这之前,你需要培养出对代码异味的感觉能力。如果你不知道好的代码是怎么样的,坏的代码看起来是怎么样的,那你怎么会想到去改进它呢。
编写可读性良好的代码我有一次听Joel Spolsky说,Stack Exchange不是针对提出问题的人进行优化,而是对阅读答案的人进行优化。为什么呢?因为相较于提出问题的个人,有多得多的人会去查看答案——应用最大化原则应该对读者进行优化,而不是提问的人。 我觉得你可以同样的方式对待代码。它可能只是由你一个人写一次。但是它可能被其他许多人阅读和编辑。你的代码具有两个功能:其一是满足你当前的工作,其二是面对在你之后的每一个人,因此代码应该始终对可读性和可理解性进行优化。 “代码编写一年后,从原作者眼光来说,也是全新的代码 — Peter Nixey 你代码里面假定什么?你的方法实际返回什么?这个四层嵌套的 if/else if and not/unless 声明究竟是在区分什么? 有时候你需要的不仅是好的变量名,你也要围绕着代码进行测试,看它究竟需要什么,并使得代码经久耐用。有效的代码是可以工作的代码,并且始终工作,即使被公司里每一个人都改过,都还能如常运行。 写的每一行代码,其读者会是那些对此不感兴趣的,或者时间紧迫的团队成员,他们可能要在接下来一年时间扩展这些代码。请记住,那个不感兴趣,或时间紧迫的人,或许就是你自己。
根据代码的生命周期来评估特性价值,而不是它的实现成本。新的开发者总是喜欢探索和发挥。他们喜欢最新最炫的东西。无论是Nosql数据库,还是高并发的移动服务,他们想尽快了解和掌握所有这些东西,用完这些玩具,就撇下一堆垃圾给下一个开发人员来擦屁股。 狗不是为圣诞节准备的,特性也不是为下一个发布版本准备的。— Peter Nixey (@peternixey) April 22, 2014 功能和架构的选择,会影响所有你在这之上构建的东西。一旦抽象泄露,你在抽象中陷得越深,就有越多的东西会被玷污,或者这个泄露导致很多东西都“中毒”。 实验性的架构和某些很炫的特性应该极为谨慎采用。优先添加你需要的功能,而不是你想要的功能。同时请注重架构。把一些实验玩具留给边缘项目。你创建的每一个组件,每一个前沿模块合并到你的项目,会快速地改变你的软件,也会让你的项目受伤或直接破坏项目。如果你不希望在项目后期除了止血而干不了其他事情,请不要首先将上述应用到你的项目中。
了解和评估技术债务技术债务是你写的代码但没有达到最优化或你想要的。它包含一些错误,虽然烦人,不过还是可以用的。它可能是一个单应用程序,不过你知道它可能发展为面向服务的程序,也可能是一个20分钟的计划任务需要被重构为20秒。 这些成本不仅仅是累加的,而且是复合累加。爱因斯坦曾经说过:宇宙中没有什么比复利更强大的力量了。同样,在大型软件开发中,也没有什么比复合技术债务更具破坏性的了。我们见过或构建的大部分项目,哪怕最小的改变也会花费数月的时间。针对码基(code base),人们已经放弃了编写更好代码的想法,只是希望在修改的时候不至于导致站点整个崩溃。 技术债务是项目中一个可怕的负担。 除非没有技术债务。 和所有其他债务一样,应用合理的话,技术债务也会给你带来巨大的杠杆效应。— Peter Nixey (@peternixey) April 22, 2014 不仅是这样,技术债务可能是世界上最好的债务,因为你不一定每次都需要偿还。当你开发一个功能结果发现它是错误的,或者当你开发一个产品结果不能正常工作,你可以丢弃掉它们然后继续。你可能丢弃功能相关的所有优化,测试和重构。因为这些不是必须的,那就不要去写这些。这个时候就应该最大化你的杠杆,留个空白,避免错误,仅仅为你需要的测试而进行测试。 在一个产品和功能的早期,很可能你现在做的是错误的。你还处在探索阶段。你要同时以产品和技术实现为核心。这期间可以大量借用技术债务。这不是修改零星错误和进行大量重构的时候,这时候你应该集中火力猛攻直到你达到(成果的)另一边。 不过当你发现,你确信你已经到了正确的位置并走出了另外一边,这个时候需要进行梳理,并加强你的地位。把事情做得足够好来推动你前进,偿还足够的技术债务来进入下一个阶段。 对于初创公司来说,技术债务和其他许多事情一样是一场跨越式的游戏。初始的代码是试探性的代码,它应该让你快速前进,发现问题和解决方案,给你恰当的空间来建立营地。你呆的时间越久,营地系统就需要更多内容,而你需要构建更大更强来支撑 它。如果你仅仅只需要停留一周时间,不要浪费时间来构建一个可以支持十年的基础设施。 |