近期技术思考

博客半年没有更新了,自己在嘀嗒拼车的这半年里,更多的是对自己写的代码的一些反思,特此书写记录下来。

  • 代码如何写的优雅?
  • 这段代码是否写的很罗嗦?
  • 是否可以换一种写法或者是否能够应用某个设计模式很好的解决这个问题?
  • ···

谈代码的坏味道

有味道的代码永远都存在的,每个人都或多或少不定期的产生一些垃圾代码,而产生此类代码的原因一般都有哪些原因?我曾经问过自己这样的问题。常见的几个原因有以下几个:

  1. 临近上线日期了,先用这段代码工作着吧。先不改了。(这样的解决方案根据实际情况并不是不可以,但当下版本时间充足了,还是花时间重新改写下为上策)
  2. 破窗理论:代码里到处充斥者不良的代码,改动需要花很大的精力,在时间不太允许的情况下,被动的在不良代码上进行输出代码。
  3. 知识或者经验上的短板:如果在某个知识上存在认知不足,很容易用自己仅有的可怜的不良方案来解决问题,殊不知,当你了解了它,换个思路,换个写法,代码能简洁很多。
  4. 待补充···

前两个跟开发项目时的心理有很大关系。而第三条,知识方面的问题,则需要我们不能停止学习,多反思。

而你,而我,中枪了吗?三个我都中了。我在输出着垃圾代码。

以上原因都是引起软件腐烂的原因,它们会增大软件的熵。我从我们的移动总监(后文简称周)身上也学到了不少东西。周来公司的第一件事,就是干掉项目架构中不合理的地方,重新编写,并且每个版本持续重构。周做的就是变化的催化剂,虽然一开始重构丢掉了一些东西,但某种意义上,他重新定义了一部分产品,包括交互和设计中不合理的东西。

代码的坏味道都有哪些?你能闻的到吗?

  1. 简单的逻辑写的异常罗嗦与复杂,容易引起错误就不说了,即便能够正确工作也要花半天理解,难以阅读;
  2. 充斥着重复的代码:
    • 似乎没得选,只能重复?
    • 根本没意识到重复
    • 知道重复还copy & paste,偷懒一时爽
    • 开发者之间同时开发,交流不到位,重复造轮子的情况,无论是业务轮子还是复用组件的轮子
  3. 难以修改,难以扩展;
  4. 类过于庞大,承担了很多其他本应该拆分开来的工作;
  5. 函数过长,可以通过提炼新函数来缩短函数,提炼的新函数的命名是否恰当直接决定了理解的难度;
  6. 其他···

什么是优雅的代码?或者说优雅的代码有哪些特征?

  1. 代码格式整洁,能让阅读的人在最短的时间理解,那么它优雅的可能性非常的大。我们这里不谈短码编程,短码编程是另外一种意义上的优雅,某方面而言;
  2. 简单的逻辑,简单的编写,复杂的逻辑,还是简单的编写,做到这一步需要长时间的磨练;
  3. 无需注释,清晰易读;
  4. 程序的鲁棒性好,易于修改和扩展,修改引入的bug相对少;
  5. 良好的模块性,低耦合;
  6. 算法方面,简洁、高效;
  7. 其他

程序员对算法和数据结构的掌握是必不可少的,但软件工程的相关理论也十分有必要了解和熟练掌握。优雅的代码不是一朝一夕炼成的,它需要非常多的代码输出量以及对既有代码的反思。我们输出垃圾代码并不可怕,可怕的是从来不对垃圾代码进行改进或者重构。作为一个注重实效的程序猿,我容忍不了项目的的杂乱。但凡有时间,我都会对代码进行轻微的整理和改进,而整理的力度和改进同时也会受限于自己对项目的认知以及经验。而我们也要批判地思考所有代码,包括自己的。

如何写出优雅的代码?又或者说如何进行重构?

有很多关于此类话题的书。推荐三本:

  • 《重构-改善既有代码的设计》
  • 《修改代码的艺术》
  • 《编写可读代码的艺术》

在《重构-改善既有代码的设计》一书中提到了重构的一些方法,很实用,也强烈推荐读者理解每一条重构方法,结合自己的项目,进行实践。

我摘取了一部分记录了下来:

重新组织函数

  • 提炼函数
  • 内联函数
  • 内联临时变量
  • 以查询取代临时变量
  • 引入解释性变量
  • 分解临时变量
  • 移除对参数的赋值
  • 以函数对象取代函数
  • 替换算法

简化函数调用

  • 函数重命名
  • 添加、移除参数
  • 将查询函数、修改函数分离
  • 引入参数对象
  • 以工厂函数取代构造函数

处理概括关系

  • 字段上移、下移
  • 函数上移、下移
  • 构造函数本体上移、下移
  • 提炼子类、提炼超类、提炼接口
  • 塑造模板函数
  • 折叠继承体系
  • 委托、继承的取代

撸得了坏代码,翻得了好书籍,反的一脑袋好思,方可撸得了好代码。无他,仅此而已。

说了半天,坏代码能工作为什么要重构?

引用《重构-改善既有代码的设计》

  1. 重构改进软件设计
  2. 重构使软件更容易理解
  3. 重构帮助找到bug
  4. 重构提高编程速度

那我要在什么时候重构?

原则:三次法则–事不过三,三则重构

添加功能时重构

修补错误时重构

复审代码时重构

避免不清楚项目上线日期,而进行大规模重构,因为时间以及风险不可控。

多阅读同事的代码

阅读同事的代码,好处是不言而喻的。我强烈建议你在有时间的情况下,多阅读下同事的代码。无论好与坏。

在阅读他人代码的时候,觉得他们的代码写的不是很好,OK,提出你认为更好的解决办法或者提出代码中存在的bug漏洞。这何尝不是一种进步。记住,跟进代码,理解代码的函数设计、调用跳转从而分析出代码的设计思路也是一种锻炼。时间久了,会锻炼我们阅读源码的能力,同时也教会我们分辨出好与坏的代码。

阅读他人代码,如果发现竟然还可以这么设计、这么写,你就赚了!

所以,多阅读同事的代码。

学会知识的分享

公司有一个良好的分享氛围很重要,嘀嗒在朝着这方面努力。每周都会有分享会,我们移动内部也不定期会有分享。周的第一期是分享是关于Realm的,第二期我分享了LLDB调试以及UI调试,第三期是呆萌的敏捷开发相关分享,整体下来,有不少收获。而其他朋友在后面都会有分享,蛮期待的。

分享的好处:为了能够讲明白,需要自己在下面做好功课,这本身就是加强学习的过程。能讲出来,让别人学习到,本身也是快乐的。

谈责任

在这半年里,或多或少自己写的代码,由于QA部门没有测试出来,而出现在线上的情况。我常常愧疚于自己产生的代码bug出现在线上而引起用户抱怨,降低了使用体验。

然而,愧疚没用!

拿起你的担当!

第一件事,Fix the bug。

第二件事,为什么会引起这个bug。

第三件事,总结,以后如何避免?同样的事情不要在犯。

这也是我在嘀嗒学到的很重要的一课。

最后

这篇文章偏向感悟多点,也作为我重视代码质量的一个转折点。

而这条路,没有尽头···

坚持原创技术分享,您的支持将鼓励我继续创作!