头图

相信在你的程序员生涯中,肯定有过这种体验:打开一个项目,开始看里面的代码,不大一会儿就想吐了——明明是同样的逻辑,为什么好几个地方都要重新写?表达同一个意思,为什么这里用type,那里用category?更别说还有YiChuiDingYin这种神一样的变量名存在了。你不禁恶向胆边生,打开git log想看看是谁写下如此丧心病狂的代码,结果赫然发现了自己在5个月前留下的名字!于是你默默咽了一口苦水,继续给这座shi一样的建筑添砖加瓦。

你可能会想我还能怎么办呢?项目已经存在很久了,工期又永远那么紧,我一个人还能重写了它不成?就算我有这个能力,老板也不能同意啊——但凡项目还能运行,谁会愿意付出那么大成本,还冒着线上停摆的风险。

且慢...重写整个项目,和让它继续“烂”下去,并不是你唯二的选择。

你还有重构(refactor)!

按说《代码重构》这本书也是程序员经典读物之一,但它的知名度实在不高,也不太受重视。究其原因,大概业界还是更看重怎么实现功能,而不是怎么写好代码吧。

refactor

好在作为一名高龄程序员,我自己有幸供职于一家重视产品品质的公司,前一段给技术团队做了一次分享,狠狠地推荐了一把这本老书。由于我目前的技术栈是python+web,干脆就给refactoring里提到的种种代码坏味道,都找到了对应的python示例,也可以算作对原书的周边补充。(《代码重构》在国内一共两个版本,第一版示例代码是Java,第二版是JS)

原来的ppt里使用了不少内部代码,不便公开,我后面会陆续整理成纯demo,做个小系列来分享。

先来看一下什么叫重构?

重构是对已有代码进行“翻新”的操作,通过微调来小幅度地提升代码品质,当这种微调成为日常开发的一部分,总体代码质量就真的大幅提高了,还能长期维护中,一直保持这种高质量。千万别从字面上,想当然地认为重构就是“重新架构”,那种推到重来的做法,恰恰就是重构思想的反面,它的英文refactor也是一个非常专属的名词,大概可以理解成re(重新)+factor(因素,因子),很形象地表达了从微观层面进行翻新的意思。

现代IDE,基本上都内置了对经典重构方法的支持,比如我们来看一下pycharm社区版(Idea, Webstorm等JetBrains系IDE都差不多):

PycharmRefactor.png

直接提供了Refactor顶级菜单,里面提供大量重构方法,也有对应快捷键。

如果你发现一个变量名起得不好:

yi_chui_ding_yin = True

if yi_chui_ding_yin:
    print('vip')
else:
    print('normal')


def test():
    for i in range(0, 5):
        if yi_chui_ding_yin:
            print('break by vip')
            return

就可以在光标位于yi_chui_ding_yin的这个变量的任意位置时,按shift+F6调出“rename”功能,给它改个名字:
refactor_rename.png

这时你会发现所有代码中使用的这个变量的位置,都高亮标识了,这时写下你认为合适的名字,回车,所有变量改名修改完成。
refactor_rename_done.png

整个过程支持全键盘操作,行云流水,无比顺畅。你可能会觉得查找-替换也可以实现目的么,然而在一个大项目里,有大量类似的名称,查找替换的时候,你就要小心翼翼地分辨每个搜索结果,看看是不是想要的内容了;万一是个‘大众化’的名字,比如“enabled”,一下子搜出几百个结果,那真是欲哭无泪,可能就直接被劝退了。

何况rename只是重构中最常用的一个方法而已,当你习惯了extract viriable, extract methond,以及与之相对应的一组inline操作,再配合上change signature,会觉得“清理”代码这种“苦活累活”一下次轻松了不少,就像入手了一台扫地机器人帮你打扫房间一样。

当然,生活中“不会”整理房间的人,大部分并不是缺少工具,而是根本就看不到房间哪里乱(偷笑),改进方法就是先培养对混乱的敏感性。《重构》用“坏味道”来形容代码的混乱,并且总结出若干中“坏味道”的标识和重构模式,下一篇我们就开始看看这些坏味道。


songofhawk
303 声望24 粉丝