百科问答小站 logo
百科问答小站 font logo



舒服的代码和不舒服的代码,差距是怎样的? 第1页

  

user avatar   ren-min-you-dian-chu-ban-she-19 网友的相关建议: 
      

舒服的代码读起来是清晰的、整洁的,让人看起来愉悦的,像诗一样。不舒服的代码反之。

好的代码像诗一样(不是朦胧诗手动狗头)。

那么雷总写的代码究竟如何呢?人邮君为大家找到了雷总1994年写的代码片段。

这段用x86汇编写成的代码(以上是代码片段)用于清除内存驻留程序,类似内存加速工具,雷军教科书般规范的注明了代码用意,时间,作者……还细腻的用符号组成了分隔符让代码更加优雅,读起来清晰、舒适,所以雷总称之为诗一般的代码其实也不算过分。

在B站六月份的一个访谈直播活动中,雷总也在给后辈的寄语中不断强调代码要整洁,逻辑要无懈可击。

因为我们编写的代码,除了用于机器执行产生我们预期的效果以外,更多的时候是给人读的,这个读代码的可能是后来的维护人员,更多时候是一段时间后的作者本人。

人邮君发现许多程序员都遇到过这样的情况:过几周或者几个月之后,再看到自己写的代码,感觉一团糟,不禁怀疑人生。

《代码整洁之道》的作者Bob大叔就提出一种观点:代码质量与其整洁度成正比。优秀的系统往往有优秀的结构设计,层次清晰,职责单一,模块化,方便拓展和复用。功能的添加往往只是在现有的框架中添加少量代码。而且Bob大叔在书中给了我们一些行之有效的规则,涵盖从命名到重构的多个方面,只要遵循这些规则,就能编写出干净的、让人舒服的代码。

就拿函数举例吧。

  • 类和函数应短小,更短小

简化代码的一个简单方式就是不断拆分函数,一直拆分,拆分到不能再分出一个函数为止。拆分后的类和函数更加短小,能使代码可读性更高。

例如下面这段代码,又长又复杂,有大量字符串、怪异且不显见的数据类型和API。花3分钟时间,你能读懂多少?

       public static String testableHtml(   PageData pageData,   boolean includeSuiteSetup ) throws Exception {   WikiPage wikiPage = pageData.getWikiPage();   StringBuffer buffer = new StringBuffer();   if (pageData.hasAttribute("Test")) {     if (includeSuiteSetup) {       WikiPage suiteSetup =         PageCrawlerImpl.getInheritedPage(                 SuiteResponder.SUITE_SETUP_NAME, wikiPage         );       if (suiteSetup != null) {         WikiPagePath pagePath =           suiteSetup.getPageCrawler().getFullPath(suiteSetup);         String pagePathName = PathParser.render(pagePath);         buffer.append("!include -setup .")               .append(pagePathName)               .append("
");       }     }     WikiPage setup =       PageCrawlerImpl.getInheritedPage("SetUp", wikiPage);     if (setup != null) {       WikiPagePath setupPath =         wikiPage.getPageCrawler().getFullPath(setup);       String setupPathName = PathParser.render(setupPath);       buffer.append("!include -setup .")             .append(setupPathName)             .append("
");     }   }   buffer.append(pageData.getContent());   if (pageData.hasAttribute("Test")) {     WikiPage teardown =       PageCrawlerImpl.getInheritedPage("TearDown", wikiPage);     if (teardown != null) {       WikiPagePath tearDownPath =         wikiPage.getPageCrawler().getFullPath(teardown);       String tearDownPathName = PathParser.render(tearDownPath);       buffer.append("
")             .append("!include -teardown .")             .append(tearDownPathName)             .append("
");     }     if (includeSuiteSetup) {       WikiPage suiteTeardown =         PageCrawlerImpl.getInheritedPage(                 SuiteResponder.SUITE_TEARDOWN_NAME,                 wikiPage         );       if (suiteTeardown != null) {         WikiPagePath pagePath =           suiteTeardown.getPageCrawler().getFullPath (suiteTeardown);         String pagePathName = PathParser.render(pagePath);         buffer.append("!include -teardown .")               .append(pagePathName)               .append("
");       }     }   }   pageData.setContent(buffer.toString());   return pageData.getHtml(); }     

这段长代码有太多不同层级的抽象,有奇怪的字符串和函数调用,混以双重嵌套、用标识来控制的 if 语句等,不一而足。

但是,我们只要做几个简单的方法抽离和重命名操作,加上一点点重构,就能在几行代码之内解决问题。

当然,这段代码还可以再次重构。

怎么样,清爽多了有没有?

所以,if 语句、else语句、while语句等,其中的代码应该只占一行,该行大抵应该是一个函数调用语句,这样不但能保持函数短小,而且,因为块内调用的函数拥有较具有说明性的名称,还可以增加代码的可读性和价值。

  • 函数只做一件事(同一层级的事)

同一个函数的每条执行语句应该是同一层级的抽象。函数中混杂不同抽象层级,往往会让人迷惑,无法判断某个表达式是基础概念还是细节。

例如,我们经常会写一个函数需要给某个 DTO 赋值,然后再调用接口,接着返回结果。那么这个函数应该包含三步:DTO 赋值,调用接口,处理结果。如果函数中还包含了 DTO 赋值的具体操作,那么说明此函数的执行语句并不是在同一层次的抽象。

  • 自顶向下读代码:向下规则

我们想要让代码拥有自顶向下的阅读顺序,想要让每个函数后面都跟着位于下一抽象层级的函数,这样一来,在查看函数列表时,就能循抽象层级向下阅读了。这就是向下规则

《代码整洁之道》的Bob大叔就给我们了一个思路:程序就像是一系列TO起头的段落,每一段都描述当前抽象层级,并引用位于下一抽象层级的后续TO起头段落。

比如:

1.要获取查询结果,先处理查询参数,然后再判断参数合法性,然后再进行查询。(这是最大的思路步骤)

2.要处理查询参数,要先拿到传过来的参数做一些逻辑处理。 ---->getSearchFileds()

3.要判断参数合法性,要进行一系列业务逻辑的判断,最后返回错误信息,统一处理。 ----> checkParam()

4.要进行查询获取结果,要先把引入model,然后处理组装数据,最后返回。把所有组装细节都放在查询获取里面。 ----> _searchWebGameStatis()

  • 参数越少越好

参数越多的函数,调用时越麻烦。尽量保持参数数量足够少,最好是没有。

此外,注释与命名,都是非常重要的。针对这些,Bob大叔还为我们整理了很多准则和技巧,如果你也是和雷总一样有追求的程序员,可以读一读Bob大叔的代码整洁之道系列丛书,能让你的代码更加整洁,工作起来更加得心应手。

人邮君也理解有一部分小伙伴目前没有时间读书,如果没有时间系统性地学习代码整洁相关的知识,也一定要开始注意雷总说的代码逻辑问题,保证代码的逻辑性和严谨性,如果不够严谨或者逻辑有问题,那么总有一天这个bug会被触发。

墨菲定律,在软件开发上总是很有效。

关联阅读

========

赠人玫瑰,手留余香,不要忘记点赞、收藏、关注 @人民邮电出版社 哦~

一键三连,感恩有你~




  

相关话题

  为什么程序员有那么多过劳死的,知乎上还是乐此不疲的劝人转计算机专业? 
  你想告诉准程序员些什么? 
  有哪些程序员用起来舒适的键盘推荐? 
  如何做好小团队的开发规范? 
  作为程序员,你一般用什么软件画流程图时序图和状态图等? 
  C语言中, for 和 while 在汇编上有什么区别? 
  现在为什么 Python 这么火? 
  如何看待 2020 年 10 月内测版的知乎盐值体系?对此你有什么想法? 
  作为一个程序员,平均两三年跳一次槽好还是持续在一家公司好? 
  既然国外的 IT 巨头有能力推出自研发的语言,为什么国内的巨头们没有这种热情呢? 

前一个讨论
你认为美国的伟大体现在哪些方面?
下一个讨论
计算机的书籍动辄几百上千页,作为学生真的有必要啃这些大书吗?如果有必要,该如何提高效率的看书?





© 2024-11-21 - tinynew.org. All Rights Reserved.
© 2024-11-21 - tinynew.org. 保留所有权利