每个程序员或多或少都会有一些重构的经历,相信经过重构之后对于代码效率的提升也是相当明显。然而若是重构并非针对代码效率提升,甚至降低代码效率,是否有其必要?我认为对于项目而言,这也是非常必要的。
相较于开发而言,任何项目的维护所耗费的资源都更为隐蔽且大量,这种既无收益,又耗费人力成本的工作大多被安排给一些缺乏经验的工作人员来进行,之后就是新一轮噩梦的开始。当你拿着一个经过许多人删减,并运行了一段时间的系统,需要对其进行2次开发时,想必会是相当痛苦;当某个客户的需求与数年前曾经成功的项目一致性相当高的时候,面对几近陌生的代码,如何实现重用;当你进入某个新公司时,面对对方或冗余或精致的系统代码,是否有种难以入手的感觉?
注释并非是万能的,开发文档也具有片面性,你依然需要花费大量时间和精力去解读这些东西。那么这个时候,我建议尝试重构一下代码,将代码分门别类的整理。在这里,我想说一下我的灵感,对于语言要素的使用。
我们人类所使用的语言被称之为自然语言,对计算机进行编码称之为机器语言,两者之间如此相似,却又如此迥然不同。
我们所使用的自然语言,能够很好的描述事物,却又包含了语言中所没有表达出的含义,即使经过再长的时间,也能很容易的理解其中的含义,但是无法得到唯一的解释,并且根据不同的阅读者,所得到的答案也会有所差异。
机器语言可以精准的描述事物,毫无偏差,根据编译所得到的一定是唯一的答案,然而越长的机器语言,其可读性越差,若是没有相应的开发文档,想要从百万行的代码中找寻到需要的内容就如大海捞针。
究其原因即在于机器语言的语言要素发展不均衡,强大的语法规则,并不能取代语境和语意的重要性,因此也就无法保持其可读性。
对于机器语言来说,其最强大之处莫过于if语句,循环,递归,任何算法的基础几乎都是从中展开。而自然语言中几乎没有相对应的解释方式,正是这些强大的功能阻碍了代码的可读性。因此,我认为在重构时,应当将这些部分尽可能的替换成可读性较高的函数或方法,在可能的情况下,将if转换成switch。理想状态下,我认为主程序应当是如下的状态:
需要包含的程序
主程序
{
变量定义;
对象定义;
初始化对象;
条件判断
{
条件一:需要做的事情2;
条件二:需要做的事情3;
}
循环一些事情的函数;
释放定义的对象;
}
循环一些事情的函数
{
循环体
{
条件判断
{
条件一:需要做的事情4;
条件二:需要做的事情5;
}
递归一些事情的函数;
}
}
递归一些事情的函数;
{
需要做的事情6;
需要做的事情7;
递归一些事情的函数;
}
然而,我们知道理想情况不总是能够得以满足,很多时候你还是要被迫写一些较长的代码,并且无法将其拆分或封装。即便如此,我仍然建议,即使只有一行代码,若是能够增加可读性,也要将其封装出来,重构成单独的函数,特别是某些单行判断或按位操作的代码就更是如此了。
再增加了代码行的语意后,其实我们还能在函数和方法的命名中增加对前后文语境的辅助说明,这样能更好的增加我们所需要的可读性,无论是驼峰式的书写方式或是连接符的书写方式,都应该尽可能的增加其可读性,而不要节省函数名的字节数,你可以像这样来写:
在循环体之后的_用于整理数据的_最终输出为字符型的_正则表达式函数()
{
}
看上去相当冗长,令人不适,然而当许久之后,你或你的续任者,会因为这一时的不便而得到更多。
最后总结一下:尽可能的对项目进行重构;在不发生致命错误的情况下,即使牺牲一些性能或增加一些复杂度,也要以可读性为主要目的;尽可能的将自然语言的语义和语境置入你编写的代码,你下一次重读的时候一切都不会白费。
PS:相对于高级语言,低级语言应该避免这部分的工作,毕竟对于汇编语言来说,性能高于一切;移动设备的重构,目前也应该以性能作为优先考虑。