程序员对具体的技术的掌握的确很重要,因为程序员就是使用这些技术来编码代码的。但真正决定一个程序员的能力及未来的可朔性的,只能是编码之道。
那究竟做为一个程序员,我们要如何追求编码之道呢?
本周,继续聊编码之道,这是第六篇,本系列的其它文章为:
- 编码之道(一):程序员的"圣经"
- 编码之道(二):软件的价值
- 编码之道(三):编码的困境,失衡的价值
- 编码之道(四):编码有术,术中有道
- 编码之道(五):变化的术,及永恒的道
进阶之路
从我个人的经历,对于一个程序员的成长之路,我把它大致的分为以下几个阶段。就如同修行一样,我们要一步一步来。所以,我把这个称之为程序员修"道"之路。
- 术的学习与提升
- 代码简洁之道
- 原则与模式
- 测试驱动与重构
- 抽象与架构的能力
- 新的尝试
如同阶梯一样,我认为你可以一步一步的去尝试做这些事情。而一旦你去这样做之后,你就会慢慢发现,自己对编码的理解会不断的有新的想法。
接下来,我逐一说下我对这些阶段的理解。
术的学习与提升
从某个点开始,你成为了一个编写代码的程序员,也许你用的是Java从事的后端开发,也许是Vue或React前端开发,这些都不重要。
重要的是,你开始了一个新的阶段。也就是成为程序员的第一个阶段。
在这个阶段,也就是第一阶段,你需要唯一做的一件事就是:
不断的去学习与尝试你所用的技术
比如Java语言,或React框架等,这些具体的术,你要用心的学习,更重要的是不断的尝试。编程这个东西,光看是没用的,重要的是不停的去写。
关于术的学习,我有几个建议:
- 一定要重视官网,要反复的去阅读官网的文档。
- 再选择一本好的书辅助学习
- 不断的尝试
如果你能这样做,很显然,随着时间的推移,你会成为一个有经验的程序员。也就是当下一步你去寻找工作,或被评估时,别人如果问你一个React的什么机制或技术点,你就会很清晰的回答上来。
这种程度,你就足以让别人认为你是一个优秀的程序员了。但真实的状况是:这仅仅是一个开始而已。
代码简洁之道
对术的学习与提升并不只是一个过程,它是你一直需要做的事。
但很多程序员就满足于仅仅如此,不再前进。这显然不够。
在不断的学习术的同时,下一步,你需要去关注的就是:
让自己的代码更加简洁
实现一个功能的不同的代码,可能在功能完成度以及性能上都没有太大的差别,但简洁度却天差地别。
让程序员写出满足功能的代码,这并不是非常困难的事,但如果希望他们写出足够简洁的代码,或者让他们本身有追求让代码更简洁的欲望,这个就不简单了。
但这是一个优秀的程序员必不可少的一个阶段,如果一个程序员连追寻让自己代码更简洁的欲望都没有,很难想像他能成为一个优秀的程序员。
原则与模式
在没有开始系统的学习原则与模式这前,你不可能编写出优雅的,易于维护的代码。
事实上,想让你的代码更简洁,原则与模式都必不可少。
大多数程序员可能都在用面向对象的语言,那以下这些原则与模式是必须得去学习的
- 面向对象的三大基本特性:封装,继续,多态
- 面向对象的五大基本原则:单一职责原则 ,开闭原则,里氏替换原则,接口隔离原则,依赖倒转原则
- 常见的二十多种设计模式
- 在架构层面,也有一些常见的架构模式或风格,如分层架构,领域驱动设计模式,六边型架构模式等
程序员需要理解这些原则与模式,更重要的是在日常编码过程中,不断的应用与实践它们。
测试驱动与重构
国内的程序员可能对这两个都比较少真正实践,包括编写单元测试以及重构。
但是我们去看那些优秀的语言或框架时,哪一个没有单元测试?哪一个不会重构?想要成为一个优秀的程序员,这两者都是不可或缺的。
而测试驱动与重构这两个是可以放在一起说的。它们是互为补充,互为依赖的。
测试驱动是重构的前提,没有单元测试的前提下说重构都是不现实的。而重构则会让你代码越来越好,越来越简洁与优雅。
也许你认为你没有时间编写单元测试,也许你的公司或团队没有给你足够的环境让你去做这些事,甚至你都不觉得写单元测试这个事有多重要。
不管如何,如果你想成为一个优秀的程序员,测试驱动开发与重构都是你不得不做的事。
如果你总是让那些借口去阻碍你做这些事情,这就相当于一个门槛,你将无法跨过门槛。
抽象与架构的能力
抽象的能力
这其实是两个能力,但它们也是互为补充与依赖的。
第一个是抽象的能力。
什么是抽象的能力,我举个例,后端编程人员熟知的JPA或Hibernate框架,前端也有类似的TypeOrm及Sequelize,它们都是抽象的产物,你用它们编写同样的代码,而可以不用考虑后面真正用的是MySQL还是Oralce等数据库。
所以,抽象能力就是:
分析与寻找不同东西的共同点,将它们的共通性提升至上一层,将差异性下降至下一层。这就是抽象
比如在myddd-vertx的媒体模块实现中,我把不同的媒体实现抽象出来
这样,在日后使用媒体模块时,我就可以这样做
代码语言:javascript复制 when(media){
"local" -> implementation("org.myddd.vertx:myddd-vertx-media-storage-loca:${rootProject.extra["myddd_vertx_version"]}")
"qcloud" -> implementation("org.myddd.vertx:myddd-vertx-media-storage-qcloud:${rootProject.extra["myddd_vertx_version"]}")
else -> implementation("org.myddd.vertx:myddd-vertx-media-storage-gridfs:${rootProject.extra["myddd_vertx_version"]}")
}
这样,我的整个项目事实上并未依赖任何具体的媒体技术,而是依赖了抽象出来的东西。我可以灵活的切换使用任何一种媒体实现。
这便是抽象的能力。
一些程序员,在整个职业生涯中,可能从未这样做过这样的事情,这不能不说是一种可惜。
架构的能力
如果用一句话来形容抽象与架构能力这两者的关系,那就是:
不谋全局者 不足以谋一域,不谋大势者 不足以谋一时
抽象的能力是一域或一时,而架构的能力就是全局或大势了。
架构的能力更多的是对全局的掌控的能力。就是你做为一个程序员,是否具备独立把握全局的能力。
举个例来说,最近在做一个项目,设计一个微服务架构,最开始我设计是基于Kotlin Vert.x gRPC EventBus的架构
后面,公司考虑到vert.x这个技术太不大众与主流,风险太高,不是非常愿意接受。
于是没办法,我又基于Spring Boot设计了个在概念上几乎完全一致的架构。这个架构基于Spring Boot Dubbo 3的
这两个不同的架构,事实上它们非常相似。
比如,它们在模块与分层上完成一致,领域驱动上的概念也几乎一致,甚至在同时支持单机构建与分布式构建上也完全一模一样。
代码语言:javascript复制#以下构建命令,在上述两个架构中都是支持的,理念与结果几乎完全一样
#local=true表示打包成一个JAR包,以单机的方式运行。而local=false表示按模块构建,以微服务的模式部署与运行
gradle clean build -Plocal=true
而在模块实现上,我又基于Java Spring Boot上又实现了一个和myddd-vertx几乎完全一致的媒体实现。
这便是架构的能力,但很显然你可以看到,架构的能力是建立在抽象的能力之上的。
一旦你有足够强的抽象能力,就算在架构这个级别上也能基于不同的技术框架抽象出类似的架构。
这两个微服务架构都已经纳入我的myddd开源框架中了,后续会介绍出来,有兴趣的可以关注微言码道公众号或访问myddd的官网:https://myddd.org
新的尝试
许多程序员,可能整个职业生涯中都在与一种语言或一个框架打交道。
比如,Java,抑或Spring Boot?
确实有部分程序员,一旦习惯了Spring Boot,可能在日后再也不太愿意用其它技术了。
好吧,我承认Spring Boot也许当前确实足够了,一直用它是个稳妥的选择。就比如我的公司,不太愿意用Vert.x一样,这种追求主流的心态是可以理解。
但有一个不可忽略的点是:
技术上没有永远的主流
术的东西是易变的,今天流行的东西,明天一定会没落。今天时兴的语言,明天就没有它了。这是永恒不变的真理。
所以,程序员修"道"的至关重要的一个点就是:
去做新的尝试
去使用你不太熟悉的技术,去做你不太熟悉的方向。唯有如此,你对技术的理解才能慢慢不断进入新的境界。
这也是我的经历与感悟,2015年的时候,我做为一个后端架构师当时选择跳入Android开发,又在2015年底在公司iOS团队快崩盘的时候跳入iOS开发。而在2020年又去基于前端技术做一个基于Electron的跨平台桌面开发,这些尝试与经验不仅造就了我今天全栈式的技术能力,更重要的是:
它让我对技术的理解进入了一个新的阶段
这种经验对我来说,是弥足珍贵的。我还清晰的感受到,当时从Android转向iOS时,从Java这种语言,转向OC时,那种生疏感以及不知所措的感觉。(因为OC做为一门面向对象的语言,与其它主流面向对象的语言语法及风格相差过大)
做为一个后端程序员,难道你从未想过使用Go?或像我在2021年选的的Vertx响应式编程?
做为一个前端程序员,React和Vue对你来说难道不是可以相互切换的技术选择?
做为一个移动程序员,原生开发,或RN开发,或Flutter开发,难道它们不是各有优劣的选择?
或者更进一步,从你熟悉的方向跳入另一个方向?
不去尝试新的东西,你对技术的理解就只能停在你熟悉的技术上,很难有新的感悟与理解了。
相互交织的阶段
当然,上面说的每一个阶段,并不是一个阶段一个阶段来的,它们只是一种笼统分类。事实上,它们更多的是相互交织的阶段,也就是无论什么时候,你都需要对上面说的每一个阶段去用心。
做专业的程序员
如果有一个词来形容如何做一个程序员,我能想的唯一一个词就是:专业性,专业这个词足以包含一切对成为一个优秀的程序员的要求。
所以,怎么样才能算是一个专业的程序员?
下一篇,编码之道(终): 做专业的程序员