去年这个时候,要开发一个新的功能,主要就是与别的程序进行通讯,并解释相应的XML协议包,根据这些协议包功能进而向服务器转发相应的命令,然后当服务器回应之后再组XML协议包发送给原来发送命令过来的程序。就这么样一个功能,大概有10个XML协议包,这个员工设计这个功能,就只写三个类:接收XML数据类、解析XML协议并处理类、回应包XM协议打包类。这样的设计,在起初两三个协议包时,工作起来还是很正常,当协议包达到10个之后,就发现问题很多了。要么重发组包不对,要么解析数据不对,要么回应之后找不到相应的对象等等。越到后面,发现问题越多,由于此功能还有很多用户在等着使用,项目紧急,当我去审查代码时,发现这样一种情况,所有代码就写在这三个类里,每个CPP文件都已经超过7000行大小,每个函数也很长,要显示几屏才可以显示完,嵌套的循环和判断语句超过四层。刚从这些表象看来,就是一种不好的征兆,让人感觉代码设计不好,编程的习惯不好,这样的代码怎么可能表现出来高质量?高效率?
由于项目紧急,只能先在原来的基础上,作了一些基本的修改,主要缩短函数的大小,让每个函数至少在两屏幕之内显示完,另外把多层嵌套循环和判断分成小函数调用。经历过这两样修改之后,代码质量提升了不少,解决BUG的效率提升了。也许你会问函数大小真有这么重要吗?有这么神效吗?我可以肯定回答,无论任何语言,只要把函数变得足够小,只做一件简单的事情,就是最重要的事情,因为函数是一个软件里最基本单元,就像建高楼的砖块是一样的,如果砖的质量不好,这样高楼是无法达到数百层的。同理函数写得太长,导致一个人理解它的速度就会降低,同时需要翻多屏时,就记不住上面的变量和意义,又需要再回滚回去,导致屏幕不断回应滚动,时间就比别人只写一屏两屏大小函数多很多,在调试时,就不能在眼底下查看所有相关内容。因此函数要写得尽量短,别人说“天下武功唯快不破”,我说“天下软件唯短不破”。
另一个问题,就是多层嵌套循环和判断。这个问题,在我以往的文章里也有写过,但是还有很多新进入软件行业的新人,还是前赴后继,继续发挥这个“传统”,这让我感觉到还是要大力呼喊,大家能否多考虑一下这个问题,能否改掉这个坏习惯?首先,如果嵌套循环超过三层,就不要写第四层了,要立即把第四层内容写到一个小函数里,在前面三层循环里调用这个小函数。其次,就是判断语句的嵌套,如果超过三层,也应立即把里面的内容改写到小函数,这样达到层次不超过三层。最后,通过上面两点修改,肯定可以把函数变小,从而也达前面函数短小的,一个函数只做一件事情的目的。
通过上面两个修改,只能免强可以让功能实现起来了,基本上能使用。但是扩展性、可维护性还是很差,根据没有高大上的感觉。因为每个CPP文件还是很大,达到7000多行,当想查找某一个功能时,就需要回来滚动,以及重新编译,你想像一下,一个CPP文件如果只1000行,分成7个文件,一般情况下只会只修改一个文件,那么编译时可以只编译其中一个文件1000行即可,而不是目前的7000行,从这里来看就可以提升效率很多。另外,由于设计类过少,这才是个大问题,把很多功能全部融在一起。针对这个问题,在后面的时间里,立即调整了设计,把所有XML协议包分成一个类,这样每一个协议包的功能都在一个类里,再添加一个协议,就增加一个类的方式,这样扩展就很方便了。同时协议类里采用基类实现相同的功能,不同协议类采用派生类来实现的方式,达到相同代码复用,不同功能分成不同类,并且提供相同的虚函数,再通过派生类重载虚函数提供不同的功能处理。经过这样整理,写了很多类,每个类功能都实相应的数据结构和算法,无论从维护和查找BUG的时间,都大大升级了。
从这段经历里,可看到类不是少就是好,应是多写一些功能类,同时多写一些CPP文件,这样可以减少类代码的大小,减少CPP文件里代码的行数,坚持采用面向对象设计思想:对象+对象=软件,数据结构 + 算法 = 对象。
蔡军生 QQ:9073204 深圳