这一周撸了个懒人通讯协议代码生成器fastbin,这个工具会分析指定的Go代码,提取结构体信息,然后为每个结构体生成二进制序列化和反序列化的方法。 生成出来的代码符合encoding包中定义的BinaryMarshaler和BinaryUnmarshaler接口要求,此外还支持更高效的序列化和反序列化方式。
fastbin使用的序列化格式并没有任何特别之处,没有Protobuf的可选字段也没有Flatbuffer的随机访问功能,简单到可以说是简陋。
之所以开发这个工具完全是从项目开发流程的角度出发。
在我们过往的项目中,一直用一套自定义的协议描述语言做协议描述,然后用这些协议描述文档来生成对应的服务端和客户度代码,这也是Protobuf、Flatbuffer等工具的流程。
这种基于配置的开发流程有个问题,在开发的时候经常需要在配置文件、命令行、生成物、功能代码之间来回切换,这样的切换很容易打断思维的连贯性。
关于思维连贯性,我有个亲身经历的笑话。
有一次我要激活个软件,SN在我Gmail邮箱里,我打开Gmail邮箱时发现公司的自动科学上网打不开Gmail,于是我就开始研究公司的科学上网哪个环节出问题,最后定为到是dnsmasq的配置问题,我就去整配置。等我都配置好,打开Gmail了,我对着电脑在那里想了好久我刚才是要干什么来着?
其实这样的事情也会发生在开发过程中,我们项目开发过程中会涉及到各种工具各种配置,这些事情每一样都分散我们一点精力,其实无形之中给我们带来的很多额外的精力损耗。这种精力损耗不但影响开发效率甚至也影响到产品质量和做事的积极性,因为人的精力是有限的,当一个事情做起来步骤很多很繁琐的时候,人自然而然的就会减少做的次数,甚至从潜意识上排斥去做它。
所以我希望我们的项目开发过程中,工具可以是在手边的,拿来就用,用完放下,不干扰,不分散精力。这样大家可以更专注于项目本身,而不是开发流程中的某个环节。
我思索下来,觉得要做到这一点,最直接的方式就是用代码自身作为配置,工具反过来从代码里提取信息,这样整个开发流程中就不再需要来回切换了。
所以fastbin的特性就是零配置,fastbin的fast并不是指它的执行效率有多快数据结构有多优秀,而是指它的开发效率高,按需求写代码就可以用了。
Go因为内置了Go的Parser,所以解析Go结构体并不难,此外Go内置的Template包也给代码生成工具省了很多代码,提高了代码可读性。
fastbin还用了Go的generate命令,只要在需要生成代码的文件头加一行注释,就可以用"go generate"命令生成这个文件的fastbin代码。
如果你对这个工具或者思路感兴趣,欢迎到项目主页看看,欢迎提交Issue和PR。
上善若水,水善利万物而不争。
有疑问加站长微信联系(非本文作者)