什么样的代码才算好代码 (舒服细致的代码)

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

什么样的代码才是好代码,好代码和烂代码的区别

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

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

什么样的代码才是好代码,好代码和烂代码的区别

什么样的代码才是好代码,好代码和烂代码的区别

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

什么样的代码才是好代码,好代码和烂代码的区别

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

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

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

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

什么样的代码才是好代码,好代码和烂代码的区别

代码整洁之道(异步图书出品)

代码整洁之道(异步图书出品)

¥77.9

购买

就拿函数举例吧。类和函数应短小,更短小

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

例如下面这段代码,又长又复杂,有大量字符串、怪异且不显见的数据类型和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("\n");
      }
    }
    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("\n");
    }
  }
  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("\n")
            .append("!include -teardown .")
            .append(tearDownPathName)
            .append("\n");
    }
    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("\n");
      }
    }
  }
  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大叔的代码整洁之道系列丛书,能让你的代码更加整洁,工作起来更加得心应手。

什么样的代码才是好代码,好代码和烂代码的区别

什么样的代码才是好代码,好代码和烂代码的区别

整洁之道三部曲:代码整洁之道+代码整洁之道

整洁之道三部曲:代码整洁之道+代码整洁之道 程序员的职业素养+敏捷整洁之道 回归本源(京东套装3册)

¥175.9

购买

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

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