编程很像写作 —— 你应该从一个能用的“不完美的初稿”开始,再通过两三次修改,逐个解决初稿中存在的问题。
工程师们肯定会嘲笑自己居然被轻率地比作了”作家“—— 但是今天早上的文档又是谁写的呢?你不是在“写代码”吗?
软件开发人员从事着最具创意的工程类型的工作。毕竟,与构建桥梁的土木工程师相比,软件工程师在构建应用程序时可以发挥更多自己的创意。
在具有创意性的行业中工作意味着你可以向那些写文章的作者身上学习到很多的东西。那些常常被推荐用于解决写作困难的方法也是最好的写作建议之一。
下面让我来向你推荐“不完美初稿”的技巧 —— 因为它让你成为效率更高的 “coder”。
”不完美初稿”的诀窍
“不完美初稿”的诀窍非常普遍,即使没读过网上那些各式各样的关于写作的博客,那你也可能早在英语课堂上就听说过。
“不完美的初稿”的关键就是,即使你的初稿写的非常的糟糕,但是你也只需完成初稿就够了 —— 因为任何初稿都比什么都没有的空白页强。
编辑修整自己的作品要比从头开始编写要容易的多,所以,你应该立即尝试地编写一些内容(不管是什么内容都可以)只要能让自己的代码可以正常的工作。
换句话说,你今天要在午饭前写完 100 行(有效)的不完美的代码还是 0 行的完美代码呢?
当然,最后的结果都是,你会用以上任何一种方式完成 50 行完美的代码。但是编写“不完美的初稿”能带来心理上的优势:你将在承受较少压力的情况下获得更大的成就感。
你将会享受编码的快乐!难道还有什么比这个更重要?
我该如何开始创作一份初稿
我更倾向于以“简单的初稿”为编码的起点,因为“不完美的初稿”似乎是对我的编码能力的一种否认。
你是否想成为一位写“不良代码”的“不良程序员”,因为你读过有关编写“不完美的初稿”的建议?
不,你想成为一名“成功的程序员”,编写“出色的代码”,因为你正在遵循从“简单的初稿”开始编码的技巧。
如果你曾经复制过一个代码示例,然后对其进行了调整以供自己使用,那么实际上你已经学会了“简单的初稿”的诀窍。
使用代码示例时,你不可避免地要进行很多更改,但关键是首先要使代码能够工作,然后马上对其进行改进。
无论你是编码的新手还是专家,你都可以使用“简单的初稿”的方法来完成任何的编程任务。
为什么“简单的初稿”非常有用
当你编写了有效的代码时,你就会感到很有成就感,这使你拥有了更好的心态。简单的代码更有可能第一次编写就能成功。
另外,简单的代码易于编写,从而节省了时间。的确,它可能看起来重复又啰嗦,你机智的大脑也会恳求你去找出一个更简洁、高效的“更好”的解决方案。
忽略它
诀窍是在有这些感觉时先喝点饮料,然后在追求简单的道路中勇往直前。等到代码生效后,你将立即对其进行重构 —— 在拥有能够正常工作的版本之后,你就可以让自己想法变得更加复杂。但是在这之前,请让事情尽可能的简单。
写作教练August Birch把这个称作“分步式写作”:写下整个内容,接着立即将它修改润色,完善和修改不断交替。
但是在这一点上,编程和写作有所不同:因为代码必须可以成功执行,所以开发人员都知道什么时候第一稿算是“足够好”。当你的代码正常工作时,这就是立即修改“简单的初稿”的信号,并在进行下一步之前对其进行多次的完善。
对于任何只是学习编码的人,这个方法都会提高两项关键技能:编写有效的代码,并在不破坏正常运行的前提下改进代码。
简单的代码示例
我最近通过领英平台指导了一名初级工程师,他正为一个过于复杂的编码挑战而苦苦挣扎。尽管一旦你需要在真实的项目中实践时,这样的编码挑战就变得没那么有用,但它是如何编写“简单的初稿”的一个很好的例子。
由于问题很复杂,所以他打算尝试编写一个复杂的解决方案。让我们来看看这个挑战:
“编写一个函数addWeirdStuff
,该函数将arrayTwo
中所有奇数的和与arrayOne
中每个 10 以下的元素相加。类似地,
addWeirdStuff
还需要将arrayTwo
中所有偶数之和与arrayOne
中等于或大于 10 的那些元素相加。另外:如果
arrayOne
中的元素与arrayTwo
中大于 20 的元素相加时,还需要额外加上 1。
值得注意的是,就像在现实生活中一样,他得到了不完整的需求说明:函数 addWeirdStuff
应该返回一个新数组,新数组包含来自 arrayOne
以及 arrayTwo
的项。
他最开始尝试用一个 for
循环来解决这个问题,但是最终没有成功。 这是一项复杂的认知任务,对人的工作记忆(工作记忆是短期记忆的另一个称呼)一定是个挑战,而他对此一筹莫展。
这个人曾经为了解决另一个代码难题联系过我,因为他不小心将 return
语句放入复杂的 for
循环中。他还没有准备好编写简洁的代码。
我告诉他,他需要使用两个单独的 for
循环,为了简单他应该使用 for…of
进行循环。以下是 JavaScript 代码,以及为检查他的代码是否有效的测试:
这个代码写得很丑陋,效果很差,但是它可以用!并且它具有超强的可读性,特别是对于那些刚刚开始努力学习基本概念的初学者来说。
下一步就是完善这个“简单的初稿”。
重构时间
重构,不管你对它是爱是恨,单对于写文章的作者们来说,就相当于一个编辑和修改的过程。在编程和其他类型的写作中,如果是你自己编写的文本(尤其是立即完成),修改会变得更加容易。
首先使用简单的语言来降低文本的复杂性,然后立即进行编辑修改。这个方法适用于所有类型的写作,包括编码。
我从上面的“简单的初稿”进行了重构:
这仍然是一个具有挑战性的问题,还有很多其他方法可以解决此问题,但是这个版本朝着正确方向迈出了重要的一步。
在此版本的初稿中,我加了 reduce 函数因为我更喜欢在代码中使用函数式编程
记住:“完美是好的敌人。”这只是你的初稿,你可以再次编辑!那是分步式的过程。
我还将可读性的优先级提高了,可读性高于性能, 因为我在每个内部循环中使用了 .some()
。这是 O(n²) 的双层循环。对于小型的数组矩阵,这对性能没什么影响,但是这样的操作可能会让你找不着工作。在我的下次一次重构的版本中,这也是不是重要的优化项。
我决定在完成“简单的初稿”前,我又使用 .map()
进行了一轮变更:
这是一个 “被改善的初稿”。我将两个 for…of
循环改成使用一次 .reduce()
、一次 .some()
、以及一次 .map()
。我更喜欢这种编码风格。但是老实说,我的初稿没有什么“错”,因为它是能用的,不是吗?
现在,是切换编码任务并决定明天再次审阅此段代码的好时机。
应用于的真实编码场景
在实际工作中,我们经常会收到混乱的需求说明以及最晚交付日期的压力,特别是在使用新的 API 时。每个编码人员有时都会想:“为什么这段代码不能正常的工作?”
对于我指导的这个学生来说,他从无法将问题概念化到轻松解决问题,因为他是从简单的for…of
循环开始的。得益于“简单的初稿”,他没有感到困难和挫败,反而感到成功和成就。
如果你更有经验,很自然的就能使用 .reduce()
来解决问题,那就大胆试试吧!但是如果你需要查找语法,看看是否在不查找语法的情况,对代码进行重构。因为在编码阶段你是可以一直对代码进行修改的。
同样地,如果你用的是 JavaScript,你可能希望能在在返回中增加类型检查。这作为一个编码挑战,这不是必需的,可以第二天再考虑加上。
在现实世界的其他场景中,“简单初稿”编码方法的缺点在于你将频繁进行 git commit:至少,在进行分步式开发时,需要频繁提交初稿的每个版本。在完成初稿前,你可能已经提交了三四个工作版本。
如果在后续的工作中发现了问题,你会对之前的多次提交感到庆幸,因为你可以根据提交发现问题所在并找到解决方案。
另外,代码的提交次数能给我超级大的驱动力,特别是当我远程办公时。
测试
根据你对测试的个人偏好,完全可以在写代码之前写测试。只需遵循相同的方法即可:写尽可能简单的测试,然后在测试代码可以正常工作后立即对其进行重构。
或者,像大多数程序员一样,你可能更喜欢在有一段可以工作的代码之后进行测试 —— 这也完全可以,在编写代码并将其重构一次或两次之后,编写一些简单的测试,然后再对测试代码进行重构。
我知道写代码的最快方法是完全执行以下操作:
- 写简单的代码
- 写简单的测试
- 用简单的测试重构简单的代码
- 重构简单的测试
就个人而言,我发现专注于“不完美的初稿”(或我喜欢说的“简单初稿”)使我更有可能先写测试,因为我并不在乎写的测试是否是完美的。
你甚至可以考虑将测试视为工作的“第二稿”,把测试任务推迟到明天。千万别忘了测试,就当是一切都为了你自己,你的项目和你的公司。
结论
无论你是代码新手,初级工程师还是专家,只要你不专注于完美,都将可以更快地写更多代码。从“简单的初稿”开始,然后在代码生效后立即对其进行休整。
从一位技术作家那里获取经验,该作家去年使用 10 种编程语言撰写了 100,000 个有关 JavaScript 的文字 —— 这个写作技巧对开发人员和作家均适用。
我对所有级别的程序员的真正建议是,你的初稿应该重复,甚至感觉像是“黑客”。首先忘记基本的编码原则这篇文中所倡导的(不要自我重复),然后再坚持最基本的编码规则:
“KISS” (Keep It Simple, Stupid!)
一旦你做到了这一点,你就可以使你的代码变得漂亮,但是如果你必须花费数小时的调试时间,那么一整天的工作就会花光了 —— 甚至无法让那段代码正常工作。相信我,我就经历过!
而且,如果你只是在学习新的编程语言,开发工具或代码库,则此建议是强制性的、必选的。
编码快乐!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。