前言
我有一个梦想,我写的代码,可以像诗歌一样优美。
我有一个梦想,我做的设计,能恰到好处,既不过度,也无不足。
这种带有一点洁癖的完美主义就像一把达摩克利斯之剑,时刻提醒我不能将就、不能妥协。
完美主义的代价使我在很长时间持续地迷茫和焦虑,甚至一度感到失望和怀疑。在软件的世界里,到底有没有优雅的代码和整洁的架构呢?
每每看到“剪不断、理还乱”的代码,我都会感到懊恼和羞愧。懊恼的是,不知道如何能有效地治理混乱、控制复杂度;羞愧的是,我真的无能为力吗?
一边是无止境的业务需求,一边是补丁加补丁的业务代码,开发人员被夹在中间,像一只困兽,向左走,还是向右走?方向在哪里?我倍感困惑。就像Robert C. Martin说的:“不管你们有多敬业,加多少班,在面对烂系统时,你仍然会寸步难行,因为你大部分的精力不是在应对开发需求,而是在应对混乱。”
的确,软件是具有天然的复杂性的,而且不可能彻底地消除这种复杂性。不甘于向复杂度屈服的我们,花了很多时间研究复杂性的根源,随着对复杂性理解的不断深入,我们发现造成软件复杂性的主要因素如下。
软件的本质复杂性。《人月神话》的作者Frederick P.Brooks.Jr曾说:“软件的复杂性是一个基本特征,而不是偶然如此。”问题域有其复杂性,而软件在实现过程中又有很大的灵活性和抽象性,导致软件具有天然的复杂性。
缺少技艺。“写代码”作为一种技能,入门并不是很难。但是要像高手那样优雅地“写好代码”并不是一件容易的事,需要持续地学习和实践。
糟糕的技术氛围。在一个技术团队中,如果技术Leader只在乎分配给员工的任务有没有按时实现,从来不关心代码的质量好坏,又怎能指望团队写出“干净的代码”?
教条和妥协。我们可能不得已在不恰当的场景使用了不恰当的解决方案,造成了不必要的复杂性。我们向自己妥协、向产品经理妥协、向工期妥协、向技术债妥协,总有很多借口把设计糟糕、混乱丑陋的代码发布上线。
念念不忘,必有回响;不忘初心,方得始终。经过不懈的努力,我们的坚持和努力终于在2018年有了一些阶段性的成果,我们找到了一些切实可行的控制复杂度的办法,并沉淀了整洁面向对象分层架构(Clean Object-oriented and Layered Architecture,COLA)。COLA的诞生给了我们很大的鼓舞和希望,就像是在茫茫大海上漂流,终于看到了彼岸的灯塔。
在COLA日趋成熟之际,我迫不及待地想要将这些发现和应用整理分享出来。在探索复杂度治理的相关工作和研究中,我不止一次地感叹如果能更早地了解这些知识、掌握这些方法该有多好,这样就能避免很多不必要的焦虑,少做有缺陷的设计,少写丑陋的代码了。相信你在看完本书后也会有同样的感受,因为我相信对代码的极致追求是每个技术人员的基本动力和诉求。我们都知道“写出好代码”是比“写出代码”要难得多的要求,一个程序员的“美德”就在于他是否能为后人留下一段看得懂、可维护性好的代码。
写好代码的技艺不是一蹴而就的,它是一个系统化的工程,不是看几本书、写几年代码就能轻松习得的,而需要我们对自己的思维习惯、学习方法和工程实践进行彻底的反省和重构。本书记录了一个普通码农如何通过认知升级、知识重构、持续学习,继而转向工匠的过程。作为一个技术人,我有义务将这个过程分享出来,以期给同样在路上的你带来一些启发,缩短你“从码农到工匠”的探索路径。
由于认知水平有限,本书的很多观点可能只是一家之言,因此我更希望读者带着批判的眼光来看这本书,取其精华,并对有疑问的地方提出质疑和见解。
灵活性和没有银弹(Silver Bullet),也是软件行业的有趣之处。在这个行业里,一个问题会有很多种解法,即使是最简单的函数也至少可以写出10种不同的代码来实现。因此,知识储备、判断力和思辨力是软件行业给我们提出的更高要求,任何不区分上下文和情景的教条都有可能在实施过程中遭遇惨败。我真诚地期待读者对书中的内容进行批评和指正,如果你对本书或者COLA架构有任何想法和意见,都可以通过下面的微信公众号来联系我。
软件设计不仅是“技术”(Technique),更是一门“技艺”(Craftsmanship)。要想控制复杂度,防止系统腐化,我们不能只满足做一个搬砖的“码农”,而是要坚持自己的技术梦想和技术信仰,怀有一颗“匠人”之心,保持专注、持续学习,每天进步一点点。唯有如此,我们才有可能“从码农走向工匠”!
本书的结构
本书共分为三大部分:技艺部分、思想部分和实践部分。
技艺部分(第1~7章)
这部分详细介绍了一些实用的编程技巧和方法论,并配以详尽的代码案例。掌握这些方法论可以有效地提高我们的编程素养,培养更好的编程习惯,写出更好的程序。
第1章 命名。好的命名可以极大地提升代码可读性和可理解性,本章主要介绍命名的重要性、命名要注意什么,以及我们如何对不同的软件构建(Artifact)进行命名。
第2章 规范。在Google的代码审查(Code Review)实践中,代码是否符合规范(Norms)是最重要的检查项。在本章中,我们将了解必需的规范、如何制定规范,以及如何贯彻实施规范。
第3章 函数。有时即使你不采用任何面向对象(Object Oriented,OO)技术,只把函数写好,代码也会呈现完全不一样的风貌。本章介绍许多写函数的技巧和方法,非常实用。
第4章 设计原则。本章介绍了很多前人总结的优秀设计原则,包括最著名的SOLID,它为我们提供了非常好的OO设计指导原则,比如扩展性的终极目标是满足OCP。我个人特别推崇DIP,因为它是架构设计的重要指导原则。
第5章 设计模式。好的设计模式能够使代码具有恰到好处的灵活性和优雅性,工程师之间的沟通也会变得简单。本章没有详细介绍GoF中的全部24种模式,只重点介绍几个日常使用频率高、实用性强的设计模式。
第6章 模型。软件工程就是一个对现实世界的问题进行分析、抽象、建模,然后转换成计算机可以理解的语言,解释执行,实现特定业务逻辑的过程。本章主要介绍了什么是模型、软件工程中常见的建模方法论,以及如何运用这些模型为软件服务。
第7章 DDD的精髓。领域建模是面向对象技术的精髓,本章的主要思想都来自于领域驱动设计(Domain Driven Design,DDD),但是并没有教条地照搬,而是结合实践对DDD进行了改良、萃取和优化。
思想部分(第8~11章)
思想是比技艺更高层次的能力要求,如果说技艺是“术”,那么思想就是“道”,领悟这些道理,对我们的职业发展会大有裨益。
第8章 抽象。抽象能力是工程师需要的核心能力之一。本章介绍了什么是抽象、抽象的层次性、如何进行抽象,以及如何培养结构化思维和抽象思维。
第9章 分治。分治思想的伟大之处在于,我们可以将一个很复杂的问题域分解成多个相对独立的子问题,再各个击破。分治思想在软件领域可谓是无处不在。
第10章 技术人的素养。做一个优秀的工程师不容易,然而还是有一些特质是值得我们学习的。本章主要介绍了技术人应该具备的一些素养,以及如何培养这些素养。
第11章 技术Leader的修养。一个优秀的工程师不一定是一个好的技术Leader,一个技术Leader在很大程度上决定了团队的技术味道和技术追求。在本章中,我会介绍自己在技术管理上的一些心得。
实践部分(第12、13章)
“Talk is cheap, show me the code”,一本没有实战的技术书是难以服众的。如果说思想是务虚的最高境界,那么实践就是务实的最低要求。
第12章 COLA架构。本章主要介绍了什么是架构,重点介绍COLA架构及其背后的设计理念和设计原理。
第13章 工匠平台。本章通过COLA架构在工匠平台实际业务场景中的落地,介绍如何使用COLA来搭建一个完整的应用架构,以及如何通过领域建模来实现业务逻辑。
本书特色
本书的特色之处在于“虚实结合”——既重视思想,又兼顾实践。
所谓思想,是我们分析和解决问题所需要的底层能力。我利用大量篇幅介绍了抽象、批判思维、辩证思维,以及程序员的素养等。思想是我们构建技术大厦的底层基石,是我们必须要掌握的底层能力,它超越了软件行业的范畴,是一种哲学和世界观。
实践即COLA架构。这不仅是一本技术书,也是开源框架COLA的技术指导手册。到目前为止,我还没有看到比COLA更轻量、更简洁、可直接应用到生产系统中的应用框架。看完本书,相信你会对COLA,以及如何应用COLA进行应用架构和复杂性治理有一个全面的了解。
本书面向的读者
本书的目标读者是专业程序员。无论你使用哪种编程语言、从事哪个岗位的工作,写好代码、追求卓越和工匠精神是每个程序员都应该具备的优秀品质。
本书最适合的读者是具有一定经验、从事以Java语言为主的业务应用开发人员,主要有以下两个原因。
首先,书中所有的示例和讨论都是基于Java语言编写的。熟悉Java语言和面向对象技术,能够更好地理解本书内容,尤其是第5章和第6章,以及思想部分的内容。
其次,COLA是面向业务应用的框架,第13章的实战也是一个基于COLA和Spring Boot的业务项目,因此更适用于具有一定工作经验、从事业务开发的读者。
最后,我想特别对以下不同类型的读者说几句话。
新程序员:如果你是在校生或初入职场的新人,在追求技术宽度的同时,请一定要养成“写好代码”的习惯。充分利用这本书,写好代码,能让你站在一个更高的起点上。
资深程序员:职场的资深人士能够选择本书,说明你和我一样,还怀有一颗“不安分”的心。“种一棵树最好的时间是十年前,其次是现在”,在追求卓越的路上,我们都没有迟到,现在上路还不晚。更何况,我们多年来一直在坚持写代码,这本身就是一种胜利!
架构师:熟悉我的人都知道,我不赞成在业务团队设置专门的架构岗位,因为我认为架构是一种能力,而不是职位。如果恰巧,你就在这样的岗位上,那么请一定不要画完架构图就算完成工作,要深入代码细节中去,这样才能发现设计中存在的问题,赢得程序员的尊重。如果你对技艺部分已经比较熟悉,建议重点阅读思想部分和实践部分。
技术团队管理者:管理者的一个很重要的使命就是帮助团队成长,包括制定规范和技术传承。倘若你和我一样,不仅仅把自己定位为一个“管理者”,那么请重点阅读第11章。
致谢
感谢我的团队成员沈学良、冯贝、詹向阳、聂晓龙、廖康丽、李克华和吴才强,是你们这一两年来陪我共同探索,才促成了这本书的诞生。
特别感谢玄难,虽然您不是我的直接汇报领导,但是您的为人处世之道、务实之风,以及对技术的专注和热情都深深影响了我。是您让我明白,不论身处什么位置,只要还在技术线,就没有理由“逍遥于代码之外”。记得在代码大赛夺冠的晚餐会上,我和您提到要写这本书,您表示支持,并答应为书作序。正是有了您的鼓励和期许,我才有勇气动笔写作,再次感谢您!
最后,还要感谢我亲爱的家人:我的父母(张东方、徐凤英),岳父岳母(柯超、张小妹),妹妹(张晨琛),妻子(柯霁)和两个超级无敌可爱的女儿(张艾可、张慕溪)。写书的过程比我预想的要难得多,记得最初的两个月,我常常坐在电脑前很长时间,却不知从何写起,大纲也被反复调整了很多次。正是家人一直在我背后默默地付出和陪伴,特别是我的岳父岳母和妻子,照顾小孩,并且承担了所有家务,我才能有精力全力投入在工作和写作上。你们是我最强大的后盾,谢谢你们,永远爱你们!