hello,大家好,我是张张,「架构精进之路」公号作者。
1、烂代码的形成
写烂代码很容易,但代码写成一坨屎,还能正常运行,那就要有点水平才行。
尤其是一些经验不足的新手,根本不在乎代码质量的重要性,也没啥扩展性的考量,直接出手就是干。
可是几个月之后,他们似乎也没怎么踩坑,但随着业务的不断发展,吸引了更多的人加入到这个项目中来。
语言越来越高级、封装越来越完善,各种技术都在帮助程序员提高生产代码的效率,依靠层层封装,程序员真的不需要了解一丁点技术细节,只要把需求里的内容逐行翻译出来就可以了。
很多程序员不知道要怎么组织代码、怎么提升运行效率、底层是基于什么原理,他们写出来的是在我心目中烂成一坨屎一样的代码。但是那一坨屎一样代码竟然能正常工作。
即使我认为他们写的代码是坨屎,但是从不接触代码的人的视角来看(比如说你的boss),代码编译过了,测试过了,上线运行了一个月都没出问题,你还想要奢求什么?
所以,即使不情愿,也必须承认,别人写的代码能正常运行,且不出错,那就是牛x。
2、烂代码终究是烂代码
但是偶尔有那么几次,写烂代码的人离职了之后,事情似乎又变得不一样了。
想要修改功能时却发现程序里充斥着各种无法理解的逻辑、改完之后莫名其妙的bug一个接一个,接手这个项目的人开始漫无目的的加班,并且原本一个挺乐观开朗的人渐渐的开始喜欢问候别人祖宗了。
试问:针对烂代码就没有可解的方案了么?
3、重构之道
针对代码重构,有本经典的读本《重构:改善既有代码的设计》,非常全面的阐述了各种重构之术。
而且各种编程范式,比如面向对象编程中的类的重构和函数式编程中的函数的重构也不尽相同;各种语言,比如 elixir(pattern matching, macro),javascript(closure,FP),和 C++(OOP) 三种语言的重构手段就千差万别。
3.1 时时刻刻重构
重构代码最佳的时间点:撰写每行代码的时候,而非火烧屁股的时候。
那什么样的情况你需要进行重构呢?
有道是 bad code smells。存在下面这些让你感到不太舒服的场景时,其实是在提醒你代码该重构了。
1)当你写一段代码时,不得不从别处拷贝粘贴代码
显然,这有悖于 DRY(Don't repeat yourself)。
一段代码(文档,测试,注释)如果要被复制,那么它的逻辑就该被抽取出来,单独成文。这几乎是重构最基础的实践。
然而,这个问题,从小公司到大公司,几乎是每个系统最严重的问题之一。在我以前工作的公司,我维护过一个超过 5000 行的 C 函数,里面的 if-else 层层嵌套下的 copy&paste 让人叹为观止,添加一点逻辑需要检查七八个地方是否需要同样的逻辑,完全可以入选教材作为经典的反面案例。
2)当你修改已有代码添加新功能时,发现已有代码总感觉哪里不对
比如说,逻辑写得太绕,太复杂,太难以理解,循环太多,分支太多,状态太多等等。
这样的代码几乎跪在那里请求你的重构,不重构说不过去。
3)当你调用已有的代码(函数、类)时,不得不阅读被调用的代码才能确定怎么调用时
-
这个代码要么接口定义的不好,比如说,一个函数有十多个参数;
-
要么是文档写的不好,比如说,关键性的函数没有对接口提供足够的说明。
如果说上面所述的是纯粹的代码重构,那么这里就是用户体验的重构。
程序员的代码是什么?那是一个程序员为另一个程序员精心打造的产品,函数(或者类)的 signature,以及对 signature 的说明是这个产品的 UI。
假如你如果打开一个应用,一个个操作按钮是干什么的都不知道,总和你期望的效果不同,你是不是特别想跳起来骂娘。
4)当你写一段代码时,连带着要改很多代码
当这个场景发生的时候,代码的味道相当糟糕,意味着不仅代码本身有问题,相关代码的设计甚至架构也有很大的问题。如果没有一定功底的程序员,重构这样的代码会比较费劲。
3.2 严格自律与他律
稍微大一点的软件项目是多人一起合作完成的。
与人合作,我们要坚信两点:
-
人天性都是懒惰的,有捷径的话,绝不规规矩矩走大道;
-
人都会受到 role model 或者社区的感染,如果已有的代码库形成了一个良好的氛围,新加入的人有一种融入已有体系的紧迫感。
开源项目其实可以给我们很多启发,看看那些著名的开源项目,很多参与其中的人在他们各自的公司里都未必有这么好的习惯,但在开源项目中,项目本身的检测和社区带来的压力会让它们自律。
整个过程和代码重构看上去没什么关系,但处处要求程序员重构代码以达到比较高的标准。相信我,这么做即便大家开始不适,等渐渐建立信心之后,会自我追求更高质量的代码。
4、更应该注意的点
在你决定重构或彻底重写之前,你要先做好几件事:
-
让公司的技术负责人以及尽可能多的领导知道目前的状况。
-
要让他们清楚重构和彻底重写分别面临哪些困难,如果失败会面临什么境况。
-
你只给出意见,一定要让领导做出决定。留下可以追溯的证据,例如邮件或会议记录。
往往技术人员都比较单纯,都是纯粹从技术的角度考虑问题解决问题,很少考虑“政治”因素。
上面三点做到位,干不成,和你没多大关系;干成了,成绩比你想象的大。
上面三点做不到位,干成了,领导认为很正常;干不成,你自己也只好灰溜溜跑路。
要注意,很多时候,技术问题在技术之外花费的功夫更大。
5、总结
说了那么多,结论其实只有两条,作为程序员:
⊱ 不要奢望其他人会写出高质量的代码
⊱ 不要以为自己写出来的是高质量的代码
不写代码的人认为应该重构,重构很简单,无论新人还是老人都有责任做重构。
写代码老手认为应该迟早应该重构,重构很难,现在凑合用,这事别落在我头上。
写代码的新手认为不出bug就谢天谢地了,我也不知道怎么重构。
其实写好代码是很难
与写出烂代码不同的是,想写出好代码有很多前提:
✔ 理解要开发的功能需求。
✔ 了解程序的运行原理。
✔ 做出合理的抽象。
✔ 组织复杂的逻辑。
✔ 对自己开发效率的正确估算。
✔ 持续不断的练习。
写出好代码的方法论很多,但我认为写出好代码的核心反而是听起来非常low的“持续不断的练习”。
往期热文推荐:
-
太强了,全面解析缓存应用经典问题
-
如何把团队带成一盘散沙?
-
MD5 到底算不算一种加密算法?
关注公众号,免费领学习资料
如果您觉得还不错,欢迎关注和转发~