我2017年7月入职航宇公司,那时正值云HIS门诊系统设计完成,全面进入开发的阶段。我主要负责基础功能,其中大部分是基础字典的管理功能开发。字典简单地说就是类似“1代表男,0代表女”这样的数据。性别就是一张字典表,云HIS中的字典表有100多张。这些字典表有共性,也有个性。许多都是有名称、编码、拼音全拼、拼音缩写、本地名称、本地编码,这些算作是共同属性,但也有许多表有更多的属性,甚至一部分表缺少共同属性。云HIS项目研发时间很紧张。我要写大量的代码,代码很相似,所以经常要复制、粘贴、替换,难免会多替换或者少替换,所以还得人工复查,速度也不比全部手写快多少。随着项目的推进,有时需要统一在全部字典表中添加相同的属性,修改代码的工作量就非常大。比如需要添加一个开关属性,控制本项数据是否禁止从界面修改。总之是那种技术含量不高,快不了,但又能把人累死,还容易出错的活。
作为一个对技术有追求的人,不能总是去机器般地干活,而且论速度和质量还不如机器。我开始改造手中一个代码生成工具,让他能干那些最简单、量大的工作,即是让他写机器式的代码。我把这个工具戏称为我的徒弟。徒弟刚开始很笨很笨,机器式的代码也写得出各种错,于是我得一边手工写代码,赶进度,一边帮徒弟找错误,教他如何改正错误。写代码有难度,写一份会写代码的代码,难度是前者的十倍不止。但我相信他能大大提升生产效率,此事意义重大,哪怕花十倍的精力投入都是值得的。他的特点是干活快,但有时会写出一些初级程序员都不太可能写出来的低级错误代码。每次发现这样的问题,就得去推测发生的机理,设计正确的处理机制,然后教会徒弟。要他举一反三,那是不可能的。他只接受最死板的教学方式,学得很慢,或者说我没法教得快。但他的优点是记得牢,一个错误一旦纠正后就永远不会再犯。有时为了搞清楚徒弟犯错的机理,要做实验到深夜。为了美好的明天,只能死磕今天。
慢慢地徒弟能写出最简单最有规律的代码了,初见成效,出现新的字典时徒弟能帮我分担约40%的工作量。一般是他先把通用的代码写好,然后我在他写的基础上修改或者添加这个字典的个性化代码。但是这样有个问题,如果因为业务的需要,字典的结构发生变化,则需要重新生成代码,而我手工辛苦写的代码会被覆盖掉,这是万万不可接受的。假如结构发生变化后,不重新生成,而是手工改代码,则徒弟的作用大打折扣。实践证明结构发生变化的事情还是时常发生的。经过一番思索,我用一套方案比较好地解决了这个问题。即是在徒弟生成的代码中,留出一块区域供我手工写代码,在重新生成代码时,保留这块手工写的代码,这样徒弟可以重新生成时大展身手,又能保留师父的劳动成果。
因为前面花了时间在教徒弟上,工程的进度有些落后,所以我只能加班加点写代码赶进度,徒弟能写的他都写了,剩下的都是得我来写的。新的字典逐渐出现,徒弟能很快地写出最有规律的那部分,不符合规律的留给我来写。而我是两边赶。一方面,项目紧,花在教徒弟的时间,也影响了项目的进度,虽然我尽量将教徒弟的时间安排在下班后,但徒弟出错还是要及时处理的。另一方面要逐渐把原先划分为“没有规律生成不了”的里面找一些规律更为复杂的,想办法生成,从而把没有规律一点一点变成有规律。徒弟的能力也一点点提升,也能帮我更快地赶进度。我想,只要把徒弟教会、教强,才能走出许多IT公司每天堆积代码,不断赶工,但进度和质量始终不如人意的状态。
后来预约分诊系统、云HIS住院系统的逐步开展,对徒弟提出更多更高的要求。作为师父,要在实践中探索,总结出好的代码结构,即最佳实践方案,再教给徒弟。我要求徒弟不能仅仅是会写代码,而必须是写出符合企业级工程规范的代码。
如今,大量的机器式代码交由徒弟写,个性化的创造性的代码由人来写。他写代码速度非常快,一秒钟能写几千上万行吧,质量很高,基本不出错。在依康宝、云HIS、预约分诊系统等许多系统有大量的代码就是徒弟写的。国内外用代码生成器的案例很多,但写出来的代码都非常死板,像徒弟这种灵活度的几乎没有。我会持续地教会他更多的技能,让他能写出更多更灵活的代码。取人和机器之所长,迭代加速软件的质量和生产效率。
写于2019年10月12日