如何优雅的写出好代码?

我们曾认为软件具有天然的复杂性,而且不可能彻底地消除这种复杂性,但是应该有些办法来降低复杂性。我们花了很多时间研究复杂性的根源,随着对复杂性理解的不断深入,我们发现造成软件复杂性的主要因素如下。

软件的本质复杂性。《人月神话》的作者Frederick P.Brooks.Jr曾说:“软件的复杂性是一个基本特征,而不是偶然如此”。问题域有其复杂性,而软件在实现过程中又有很大的灵活性和抽象性,导致软件具有天然的复杂性。

缺少技艺。“写代码”作为一种技能,入门并不是很难。但是要像高手那样优雅地“写好代码”并不是一件容易的事,需要持续的学习和实践。

糟糕的技术氛围。在一个技术团队中,如果技术Leader只在乎分配给员工的任务有没有按时实现,从来不关心代码的质量好坏,又怎能指望团队写出“干净的代码”?

教条和妥协。我们可能不得已在不恰当的场景使用了不恰当的解决方案,造成了不必要的复杂性。我们向自己妥协、向产品经理妥协、向工期妥协、向技术债妥协,总有很多借口把设计糟糕、混乱丑陋的代码发布上线。

念念不忘,必有回响;不忘初心,方得始终。经过不懈的努力,我们的坚持和努力终于在2018年有了一些阶段性的成果,我们找到了一些切实可行的控制复杂度的办法,并沉淀了整洁面向对象分层架构(Clean Object-oriented and Layered Architecture,COLA)。COLA的诞生给了我们很大的鼓舞和希望,就像是在茫茫大海上漂流,终于看到了彼岸的灯塔。

在COLA日趋成熟之际,我迫不及待地想要将这些发现和应用整理分享出来。在探索复杂度治理的相关工作和研究中,我不止一次地感叹如果能更早地了解这些知识、掌握这些方法该有多好,这样就能避免很多不必要的焦虑,少做有缺陷的设计,少写丑陋的代码了。相信你在看完本书后也会有同样的感受,因为我相信对代码的极致追求是每个技术人员的基本动力和诉求。我们都知道“写出好代码”是比“写出代码”要难得多的要求,一个程序员的“美德”就在于他是否能为后人留下一段看得懂、可维护性好的代码。

写好代码的技艺不是一蹴而就的,它是一个系统化的工程,不是看几本书、写几年代码就能轻松习得的,而需要我们对自己的思维习惯、学习方法和工程实践进行彻底的反省和重构。本书记录了一个普通码农如何通过认知升级、知识重构、持续学习,继而转向工匠的过程。作为一个技术人,我有义务将这个过程分享出来,以期给同样在路上的你带来一些启发,缩短你“从码农到工匠”的探索路径。

1、命名


名为万物之始,万物始于无名,道生一,一生二,二生三,三生万物。——《易经》


命名常常被认为是编程中的细节问题,其重要性往往被低估。而所谓的工匠精神,往往就是体现在细节之处,就日本的“煮饭仙人”50年专注于做好1碗米饭。一个名字虽然并不影响程序的执行,但是却对代码的表达力和可读性有着重要的影响。

在程序员的工作中,大部分的时间都在阅读和理解代码,好的命名能够让代码的概念清晰,增加代码的表达力;词不达意的命名会破坏我们思考的连贯性,分散有限的注意力。

2 、规范


离娄之明,公输子之巧,不以规矩,不能成方圆。——孟子《离娄上》


复杂系统的前沿科学家Mitchell Waldrop在《复杂》一书中,提出一种用信息熵来进行复杂性度量的方法。所谓信息熵,就是一条信息的信息量大小和它的不确定性之间的关系。举个例子,假设消息由符号A、C、G和T组成,如果序列高度有序,例如“A A A A A A A … A”,则熵为零。完全随机的序列,熵可能最大。

由此可见,事物的复杂程度在很大程度上取决于其有序程度,减少无序能在一定程度上降低复杂度,这正是规范的价值所在。通过规范,把无序的混沌控制在一个能够理解的范围内,从而帮助我们减少认知成本,降低对事物认知的复杂度。

3 函数


把简单的事情做到极致,功到自然成,最终“止于至善”。——秋山利辉《匠人精神》


函数作为程序中最小的、最重要的逻辑单元,其在软件开发中的重要性不言而喻。如果将数据比作一道菜,那么函数就是菜谱,程序员就是厨师。相同的菜,有不同的做法,由不同的厨师做出来,味道会截然不同。

自从面向对象技术出来以后,很多工程师们把精力更多放在了对象技术上,反而忽视了函数。实际上,面向对象和写好函数并不冲突,函数也是对象的重要组成部分。相比于面向对象技术体系的深奥,写好函数要容易得多。

4、设计原则


每个人都有义务捍卫、遵守或完善原则。原则可以修正,但是不能肆意妄为。——瑞•达利欧《原则》


所谓原则,就是一套前人通过经验总结出来的,可以有效解决问题的指导思想和方法论。遵从原则,可以事半功倍;反之,则有可能带来麻烦。

在软件设计领域中,有很多这样的原则,遵从这些设计原则可以有效地指导我们设计出更灵活、易于扩展和维护的软件系统。需要注意的是,和其他道理一样,原则并非是形而上学的静态客观真理,不是说每一个设计都要教条地遵守每一个原则,而是要根据具体情况进行权衡和取舍。

5、设计模式


利用模式,我们可以让一个解决方案重复使用,而不是重复造轮子。

(With patterns, you can use the solution a million times over, without ever doing it the same way twice.)

——克里斯托佛•亚历山大


设计模式(Design Pattern)是一套代码设计经验的总结,并且该经验必须能被反复使用,被多数人认可和知晓。设计模式描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案,具有一定的普遍性,可以反复使用。其目的是提高代码的可重用性、可读性和可靠性。

设计模式的本质是面向对象设计原则的实际运用,是对类的封装性、继承性和多态性,以及类的关联关系和组合关系的充分理解。正确使用设计模式,可以提高程序员的思维能力、编程能力和设计能力,使程序设计更加标准化、代码编制更加工程化,从而大大提高软件开发效率。

6、模型


建模的艺术就是去除实在中与问题无关的部分。

——利普•沃伦•安德森(1977年诺贝尔物理学奖得主)


在软件工程中,有两个高阶工作分别是架构和建模。如果把写代码比喻成“施工”,那么架构和建模就是“设计图纸”。相比于编码,建模的确是对设计经验和抽象能力要求更高的一种技能。例如,在当前热门的人工智能和机器学习领域,建模是难度很大但非常重要的工作。

7、DDD的精髓


你可以,不代表你应该。

(Just because you can, doesn’t mean you should.)——施莉琳•凯尼恩


在第6章中,我们简要绍了什么是模型、模型在软件开发中的重要性,以及一些常用的建模方式在软件工程中的应用。本章将重点讲解领域驱动设计(Domain Driven Design,DDD),包括DDD的重要概念,以及如何进行领域建模。


8、抽象


若想捉大鱼,就得潜入深渊。深渊里的鱼更有力,也更纯净。硕大而抽象,且非常美丽。——大卫•林奇


软件行业有一个概念,对其了解越深入,我就越会感叹之前的理解是多么肤浅。在很长一段时间里,对这个概念的一知半解阻碍了我对面向对象技术,甚至是软件架构的深层次理解。

实际上,对这个概念的认知偏差,我并非个例,我接触的工程师中能深入理解这个概念的并不多。能把这个概念和建模、面向对象和软件架构进行融会贯通,并进行问题分析、化繁为简的人就更是凤毛麟角了。

9、分治


要把大象装冰箱,拢共分几步?——小品《钟点工》


分治和抽象一样,都是人类进化过程中形成的伟大智慧,也是我们解决复杂问题的不二选择。人的思维要从一个字节大幅跨越到几百兆字节,也就是9个数量级(现阶段,后面还要再加N个零)。如此复杂的问题域,如果不进行分治,是远远超出人类智力范围的。

分治的价值在于,我们不应该试着在同一时间把整个问题域都塞进自己的大脑,而应该试着以某种方式去组织问题,以便在一个时刻专注于一个特定的部分。这样做的目的是尽量降低在任意时间所要思考问题的复杂度。

10、技术人的素养


未经审视的人生不值得过。——苏格拉底


在我的工作经历中,会发现有一些技术人员成长很快,能够迅速成为团队的骨干,也有一些技术人员总是在原地踏步,工作十年和工作一年的区别并不大。渐渐地,我发现这些优秀的技术人员都有一些共同的特质和素养,从而帮助他们不断进步,脱颖而出。

11、技术Leader的修养


Leader,就是走在队伍的最前面,带领者,领路人。——金一南《胜者思维》


从我开始带团队的第一天起,有几个问题就一直在等我回答。

1)什么是Leader?

2)Leader和Manager之间的区别是什么?

3)什么是技术Leader?

4)技术Leader和其他Leader有什么不同?

本章内容主要是围绕我作为技术Leader对这几个问题的思考,以及对技术Leader的理解和定义。希望你看完本章以后,也能有一个自己的答案。

12、COLA架构


软件的首要技术使命:管理复杂度。——史蒂夫•迈克康奈尔《代码大全(第2版)》


工程师的首要技术使命就是控制复杂度。整洁面向对象分层架构(Clean Object-oriented and Layered Architecture,COLA)是我所在团队自主研发的应用架构,是我们过去两年在复杂治理之路上的一个里程碑。

COLA不仅是一个架构思想,还提供了一整套可以落地实施的框架和工具。我们可以使用COLA Archetype快速搭建一个符合COLA架构规范的业务应用,并在此基础上快速实现业务功能。

目前,COLA已经开源。自发布以来,COLA得到了社区的普遍关注和认可,并已经在阿里巴巴内外部多个团队落地。从实践情况来看,COLA在应用复杂度治理上的效果显著。在本章中,我将会详细介绍应用架构以及COLA的主要架构思想。

13、工匠平台


工匠平台,技术人自己的舞台!——“工匠平台”的宣传语


本章将通过工匠平台的项目实战介绍如何使用COLA框架开发一个业务项目,从而更好地理解COLA,并使用COLA进行企业级应用开发。


我尤其喜欢的是第11章“技术Leader的修养”。技术高手在任何公司都很重要,但是以我所观察到的情况,很多高手都是“救火队长”,哪里有火就扑向哪里,成为大家顶礼膜拜的“救火英雄”;或者有些所谓的高手只在纸上做架构,指点江山。我认为,真正的技术Leader是能够创建并且演进架构,在架构层面上帮助大家比较容易地写出好代码的人;是能够创建良好的技术氛围,以写好代码为荣,以写坏代码为耻,促使大家不停学习的人。张建飞分享了他的团队中一些很有意义的做法,使我深受启发。

好代码才是真正的银弹!COLA架构能够在架构层面上帮助程序员写出好代码、研读源代码,它是作者及其团队多年来孜孜不倦地践行工匠精神打磨出的系统产物。对于读者,我的建议是一边研读源代码,一边反复阅读本书,并进一步阅读书中推荐的其他书籍。我相信,不管你是刚入行的新人,还是工作多年、经验丰富的人,抑或是技术管理人员,都能从本书中收获良多。

本文摘自《代码精进之路:从码农到工匠》,如果你对这本书的内容感兴趣,可以移步京东购买。小编摘录的是每一章的篇首,你可以把它当做详细的大纲来看。这本书从上架一直畅销在京东榜单上,

程序员:如何优雅的写出好代码?_建模

这是一本为专业程序员而写的书,写好代码、追求卓越和工匠精神是每个程序员都应该具备的优秀品质。 

本书共有13章内容,主要分为技艺部分、思想部分和实践部分。技艺部分详细介绍了编程技巧和方法论,并配以详尽的代码案例,有助于读者提高编写代码的能力,优化代码质量。思想部分主要包括抽象能力、分治思想,以及程序员应该具备的素养等内容。实践部分主要介绍了常见的应用架构模式,以及COLA架构的设计原理。