TTCN3新执行器系列-谈谈几次伤筋动骨的重构工作

我们做新执行器的时候,已经有一个很稳定的执行器在公司内广泛使用的了,

但我们认为,新旧执行器的实现是差之千里的,从一开始我们就没有重视旧执行器的实现,也没有最大限度的重用其模块,

恰恰,后来经历的几次重大重构工作,殊途同归,转了一大个圈,最后还是回到了旧执行器的基础上。

这样的教训值得深思,或许这就是成长代价。

 

旧执行器

基于内存对象模型实现,使用了ANTLR的词法语法功能,然后构造出一个完备语义的内存对象集合,具有分析、编译、链接、运行、调试功能。最大的优势的编译速度飞快,但占用内存量大。

 

新执行器

基于语言转换模型实现,包括语义分析模块,转换器模块,运行时库模块,调试器模块等,最大优势是代码编译固化能力,但编译耗时。

 

项目开始的时候,我们的计划是这样的:

1、利用旧执行器进行词法、语法、语义分析能力,保证用户书写代码正确。

2、通过ttcn3转换器和asn1转换,将用户代码转换成c++语言,然后调用标准的c++编译器编译成库文件。

3、通过执行器外壳加载运行时库、测试套库文件,调试器模块等进行运行。

 

 

我们犯的第一个重大错误是,实现asn1到c++的转换器模块。

 

asn1是一种类型描述文件,可以在ttcn3语言中使用。

因为我们是基于语言转换模型的,所以需要将asn1类型映射成c++类型,然后通过hpp文件方式导入使用。

由于asn1文件常常非常大,甚至一个文件5万多行,累积8千多个类型,

所以转换出来的c++代码非常多,直接导致编译速度非常慢。

这个问题是致命的,困扰了我们相当长的一段时间,而且花在这个asn1转换器上的开发人力也是很大的。

 

 

我们犯的第二个重大错误是,实现ttcn3到c++的转换器模块。

 

ttcn3转换器模块是独立的,和旧执行器语法语义分析模块是分开的,当时基于这样考虑:

1、不熟悉旧执行器,不想在旧执行器上改动过多代码。

2、考虑不充分,过度自信的认为,基于旧执行器的语法语义分析后,在外层实现一个转换器就可以搞定所有问题了。

 

很长一段时间内,我们的ttcn3转换器都能满足要求,但越到后来发觉越吃力,很多转换的时候单靠语法是不够的,还需要语义支持。

恰恰,我们的方案是没有语义功能的,所以需要通过旧执行器提供额外接口实现,这样的接口越来越多,但问题依旧不能完美解决。

 

 

整个项目开发周期,我们花在asn1转换器和ttcn3转换器上的开发工作是非常巨大的,约占用了60%的时间,

但这些方案都不能100%的解决问题,导致后面的多次重大重构,可以说,基本是推倒重来了一次。

 

 

重构的方案简单介绍如下:

1、否定asn1转换器,参考旧执行器使用asn1的方式,利用公司内的codec工具(基于c实现),从编译后的dll接口中获取asn1类型,

外部使用动态类型方式进行包装实现。这样的方案,c++代码量非常少,而且和asn1代码不存在正比关系,

即使10万行的asn1文件,编译速度都可以在数秒内完成。

2、否定ttcn3转换器模块,在旧执行器内部重新实现转换器工作,语法语义转换一次完成,代码转换起来变的轻松,速度也很快。

 

从重构的效果来看,我们大概花销了以前转换模块约20%时间,就100%的重写了一次,代码量减少很多,而且能100%解决问题。

 

 

我曾经很多次的假想,如果我们一开始就使用上正确的方案,今天我们的项目或许就很成功了。

从结果看过程,往往觉得简单,但一路走过来,又有谁能清醒如一呢?

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值