最近因为项目需要在看一个开源项目的源码,这个开源项目据说在内部开发孵化了 6 年之久,前几年才开源出来。 我在看设计文档和源码中发现,它的高层设计的一致性是比较好的,但到了源码实现就显得凌乱了些。 既然是时间跨度如此长的项目,想必参与这个项目的程序员也不止一批人了,处于不同阶段的程序员都有可能参与,这样也能理解实现上的凌乱了。 看着这些有一定时间沉淀的代码,有些代码可能诞生于差不多我刚工作的年头,有些又是最近才加上的。 不免让我回想起作为程序员,与这些代码一起在时间中的成长与沉淀。
刚工作的第二年,我接手了一个比较大的项目中的一个主要模块。 在我熟悉了整个模块后,开始往里面增加功能时,有点受不了原本的 DAO 层,那是基于原生的 JDBC 封装的。 每次新增一个 DAO 都需要复制粘贴一串看起来很类似的代码,久了难免生出厌烦的情绪。
当时 Hibernate 刚兴起,觉得它的设计理念优雅,代码写出来也简洁,所以说干就干就决定用 Hibernate 的实现取代原本的实现。 重新实现原来所有的 DAO 层类,这说多不多说少不少也有好几百个 DAO 类,导致连续加了一周的班。 这是个纯粹的搬砖体力活,弄完了还没松口气又有了新问题,Hibernate 在某些场景下又出现了性能问题。 断断续续把这些新问题处理好,着实让我累了一阵子,后来反思这个决策感觉确实不太妥当。 替换带来的好处仅仅是每次新增个 DAO 时少写几行代码,却带来很多当时未知的风险。
年轻的程序员对新技术充满好奇,而且有颗冲动的心。 对新技术,我知道,我了解、我熟悉、我深谙,但我还是需要克制,等待合适的时机。 写到这里,想起了《勇敢的心》梅尔·吉普森看着对方冲过来,喊着 Hold~Hold~ 的场景。
在更早的时候,我在广东省中国银行写过一个小程序,就是给所有广东省中国银行的信用卡客户发邮件账单。 按现在各大银行信用卡客户上亿的规模,即使只是每月发账单邮件的程序也不能算小了。 只是当时广东中行信用卡刚起步,***个月只有不到 10 万客户,所以算小程序。
那个年代都是全栈工程师啊,连账单页面模板的样式都是我自己设计的,***次还犯了个小错误就是金额展示没有靠右对齐。 而且程序就部署在信用卡部的一个业务人员的独立配置的办公电脑上。 每月出账,核心交易系统下发账单格式文件,业务人员手工导入格式文件生成模板邮件,然后就开始发送了。 所以,这个小程序就是个单机程序,为了方便业务人员操作,我写了个 GUI 界面。 ***次用 Java swing 写 GUI,为了展示发送进度,后台线程每发送成功一封邮件,通知页面线程更新进度条。
当时正在学 Java JDK 还没有标配 concurrent 包,都是原生的,觉得 java 线程编程很高端。 所以我选择线程间通信的方案来让后台发送线程和前台页面刷新线程通信,一股浓浓的炫技心理。 后来导致了界面动不动就卡住等一系列问题,因为各种线程提前通知,遗漏通知等情况,代码越改越难懂。 其实用个共享状态,定时轮询即可满足的,而且代码实现会简单的多。 回头想想,成长的路上不免见猎心喜、手上拿个锤子看到哪里都是钉子。 话说回来,我还挺怀念当初设计的那个账单模板,可惜现在找不到了。 感觉比现在建行给我发的那个傻大黑粗的表格看起来好些吧,传统银行在用户体验上的路上还有多远的路要走?
我现在正看的开源代码也看到一些炫技的痕迹,具体说就是关于状态机的使用。 状态机程序是不符合直线逻辑思维的,类似 GOTO 语句,程序会突然发生跳转,所以理解状态机程序比一般程序要难。 而状态机程序又通过自定义的的内存消息来驱动,更加一层复杂性。 在我理解,状态机程序最适合的场景有真实映射领域状态变迁,什么叫真实领域状态?比如,你红绿灯就表达了真实领域的三种状态。 另外一个主要用途就是做协议解析,反应解析器当前的运行状态。 凡是使用状态机来表达程序设计实现中的伪状态,往往都添加了不必要的复杂性。
有时我经常会在一些开源项目中看到一些过度设计和实现的复杂性,而这些项目还都是一些行业***的大公司开源的。 在程序员的成长路径上,越是高阶的晋升中,行业里喜欢采用专家评审制,评委会倾向性的关注项目中的技术难点以及技术含量。 制度的倾向性也有可能导致人为制造技术含量,而不一定是匹配项目的***方案。 所以程序的技术含量和深度未必体现在表面,我「看山是山看水是水,看山不是山看水不是水,看山还是山看水还是水」。 转了一圈回来,机锋尽敛,大巧若拙,深在深处,浅在浅处,这也是我所理解的 KISS 原则。
在很多科幻小说和电影中都有很多关于未来假设,多分支可能的存在。 在科幻电影《Coherence》中假设了一种一个人存在的多版本可能,碰巧在某天重叠了。 我挺喜欢这个设定的,它来自于「薛定谔的猫」的理论实验,就是关于未来已经存在很多可能版本,我们走过的部分就形成了唯一的稳定版本。 我走了很远,停下来回顾时间线上很早的自己,得到这星星点点的启示。 而现在的驻足与回顾,都不过是借此启示帮助我们更好的迈出不论或大或小的下一步。