当前位置 博文首页 > 微言码道:编码之道(六):程序员的修练之道

    微言码道:编码之道(六):程序员的修练之道

    作者:[db:作者] 时间:2021-09-20 10:42

    程序员对具体的技术的掌握的确很重要,因为程序员就是使用这些技术来编码代码的。但真正决定一个程序员的能力及未来的可朔性的,只能是编码之道。

    那究竟做为一个程序员,我们要如何追求编码之道呢?

    本周,继续聊编码之道,这是第六篇,本系列的其它文章为:

    1. 编码之道(一):程序员的"圣经"
    2. 编码之道(二):软件的价值
    3. 编码之道(三):编码的困境,失衡的价值
    4. 编码之道(四):编码有术,术中有道
    5. 编码之道(五):变化的术,及永恒的道

    进阶之路

    从我个人的经历,对于一个程序员的成长之路,我把它大致的分为以下几个阶段。就如同修行一样,我们要一步一步来。所以,我把这个称之为程序员修"道"之路。

    1. 术的学习与提升
    2. 代码简洁之道
    3. 原则与模式
    4. 测试驱动与重构
    5. 抽象与架构的能力
    6. 新的尝试

    如同阶梯一样,我认为你可以一步一步的去尝试做这些事情。而一旦你去这样做之后,你就会慢慢发现,自己对编码的理解会不断的有新的想法。

    接下来,我逐一说下我对这些阶段的理解。

    术的学习与提升

    从某个点开始,你成为了一个编写代码的程序员,也许你用的是Java从事的后端开发,也许是Vue或React前端开发,这些都不重要。

    重要的是,你开始了一个新的阶段。也就是成为程序员的第一个阶段。

    在这个阶段,也就是第一阶段,你需要唯一做的一件事就是:

    不断的去学习与尝试你所用的技术

    比如Java语言,或React框架等,这些具体的术,你要用心的学习,更重要的是不断的尝试。编程这个东西,光看是没用的,重要的是不停的去写。

    关于术的学习,我有几个建议:

    1. 一定要重视官网,要反复的去阅读官网的文档。
    2. 再选择一本好的书辅助学习
    3. 不断的尝试

    如果你能这样做,很显然,随着时间的推移,你会成为一个有经验的程序员。也就是当下一步你去寻找工作,或被评估时,别人如果问你一个React的什么机制或技术点,你就会很清晰的回答上来。

    这种程度,你就足以让别人认为你是一个优秀的程序员了。但真实的状况是:这仅仅是一个开始而已。

    代码简洁之道

    对术的学习与提升并不只是一个过程,它是你一直需要做的事。

    但很多程序员就满足于仅仅如此,不再前进。这显然不够。

    在不断的学习术的同时,下一步,你需要去关注的就是:

    让自己的代码更加简洁

    实现一个功能的不同的代码,可能在功能完成度以及性能上都没有太大的差别,但简洁度却天差地别。

    让程序员写出满足功能的代码,这并不是非常困难的事,但如果希望他们写出足够简洁的代码,或者让他们本身有追求让代码更简洁的欲望,这个就不简单了。

    但这是一个优秀的程序员必不可少的一个阶段,如果一个程序员连追寻让自己代码更简洁的欲望都没有,很难想像他能成为一个优秀的程序员。

    原则与模式

    在没有开始系统的学习原则与模式这前,你不可能编写出优雅的,易于维护的代码。

    事实上,想让你的代码更简洁,原则与模式都必不可少。

    大多数程序员可能都在用面向对象的语言,那以下这些原则与模式是必须得去学习的

    • 面向对象的三大基本特性:封装,继续,多态
    • 面向对象的五大基本原则:单一职责原则 ,开闭原则,里氏替换原则,接口隔离原则,依赖倒转原则
    • 面向对象的那二十多种设计模式
    • 在架构层面,也有一些常见的架构模式或风格,如你领域驱动设计模式,六边型架构模式等

    程序员需要理解这些原则与模式,更重要的是在日常编码过程中,不断的应用与实践它们。

    测试驱动与重构

    国内的程序员可能对这两个都比较少真正实践,包括编写单元测试以及重构。

    但是我们去看那些优秀的语言或框架时,哪一个没有单元测试?哪一个不会重构?想要成为一个优秀的程序员,这两者都是不可或缺的。

    而测试驱动与重构这两个是可以放在一起说的。它们是互为补充,互为依赖的。

    测试驱动是重构的前提,没有单元测试的前提下说重构都是不现实的。而重构则会让你代码越来越好,越来越简洁与优雅。

    也许你并认为你没有时间编写单元测试,也许你的公司或团队没有给你足够的环境让你去做这些事,甚至你都不觉得写单元测试这个事有多重要。

    不管如何,如果你想成为一个优秀的程序员,测试驱动开发与重构都是你不得不做的事。

    如果你总是让那些借口去阻碍你做这些事情,这就相当于一个门槛,你将无法跨过门槛。

    抽象与架构的能力

    抽象的能力

    这其实是两个能力,但它们也是互为补充与依赖的。

    第一个是抽象的能力。

    什么是抽象的能力,我举个例,后端编程人员熟知的JPA或Hibernate框架,前端也有类似的TypeOrm及Sequelize,它们都是抽象的产物,你用它们编写同样的代码,而可以不用考虑后面真正用的是MySQL还是Oralce等数据库。

    所以,抽象能力就是:

    分析与寻找不同东西的共同点,将它们的共通性提升至上一层,将差异性下降至下一层。这就是抽象

    比如在myddd-vertx的媒体模块实现中,我把不同的媒体实现抽象出来

    这样,在日后使用媒体模块时,我就可以这样做

        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的

    这两个不同的架构,事实上它们非常相似。

    比如,它们在模块与分层上完成一致,领域驱动上的概念也几乎一致,甚至在同时支持单机构建与分布式构建上也完全一模一样。

    #以下构建命令,在上述两个架构中都是支持的,理念与结果几乎完全一样
    #local=true表示打包成一个JAR包,以单机的方式运行。而local=false表示按模块构建,以微服务的模式部署与运行
    gradle clean build -Plocal=true 
    

    而在模块实现上,我又基于Java + Spring Boot上又实现了一个和myddd-vertx几乎完全一致的媒体实现。

    这便是架构的能力,但很显然你可以看到,架构的能力是建立在抽象的能力之上的。

    一旦你有足够强的抽象能力,就算在架构这个级别上也能基于不同的技术框架抽象出类似的架构。

    这两个微服务架构都已经纳入我的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开发,难道它们不是各有优劣的选择?

    或者更进一步,从你熟悉的方向跳入另一个方向?

    不去尝试新的东西,你对技术的理解就只能停在你熟悉的技术上,很难有新的感悟与理解了。

    相互交织的阶段

    当然,上面说的每一个阶段,并不是一个阶段一个阶段来的,它们只是一种笼统分类。事实上,它们更多的是相互交织的阶段,也就是无论什么时候,你都需要对上面说的每一个阶段去用心。

    做专业的程序员

    如果有一个词来形容如何做一个程序员,我能想的唯一一个词就是:专业性,专业这个词足以包含一切对成为一个优秀的程序员的要求。

    所以,怎么样才能算是一个专业的程序员?

    下一篇,编码之道(终): 做专业的程序员

    cs