一.有意义的命名

编写代码时,遇到的第一个问题大概就是命名,创建一个类、一个函数、一个变量时,都需要命名。这看似很简单但一个好的命名和差的命名,可是有着天差地别的区别的。好的命名,可以让人扫一眼,就大概知道这个函数的作用是什么,甚至连大体会输出什么都知道,提升了代码的可读性。而差的命名会极大降低代码的可读性,让阅读你代码的人,花费大量的时间。

好的命名要遵循以下几点

  • 名副其实

举个栗子

bad code:
List<String> list1 = new ArrayList<>();
clean code:
List<String>  sjyXmList= new ArrayList<>();

这里问题不出在整洁度,而是模糊度,我们要能从变量名的定义上大概了解到这个变量代表的含义

  • 做有意义的区分

大家都知道同一作用范围内变量的命名不能重复,此时我们就要进行区分,而大多我是这样做的,以数字系列来命名(name1、name2…)

举个栗子

我打算定义四个run对象 代表审判员的角色和姓名,角色的最后一个字符要和前面其他字分别创建一个run对象,名字同理。

bad code:XWPFRun jsRun1=getRunStyle(para,run);XWPFRun jsRun2=getRunStyle(para,run);XWPFRun xmRun1=getRunStyle(para,run);XWPFRun xmRun2=getRunStyle(para,run);
clean code:XWPFRun roleExceptEndCharRun=getRunStyle(para,run);XWPFRun roleEndCharRun=getRunStyle(para,run);XWPFRun nameExceptEndCharRun=getRunStyle(para,run);XWPFRun nameEndCharRun=getRunStyle(para,run);
  • 类名使用名词,方法名使用动词(注意)

二.函数

1、短小

  • 函数第一条规则是要短小。第二条规则还是要短小。越短小越好,20行封顶最佳
  • if、else、while等语句,其中的代码应该只有一行,该行大多应该是一个函数调用语句(块内的函数要较具体说明性的名称)。

举个栗子

bad code:public void replaceTextBookmarks(CTBookmark bookmark, XWPFParagraph paragraph, Bookmarks bookmarks) {String name = bookmark.getName();String text = bookmarks.getRuleBookmarkValue(name);int index = bookmarks.getIndex(name);if (StringUtils.contains(text,"\n")){XWPFRun xwpfRun = paragraph.getRuns().get(0);String[] textArray = text.split("\n");List<XWPFRun> handlerRuns = new ArrayList<>();for (int i=0; i<textArray.length;i++).......}else if(StringUtils.contains(text,TEXT_BLOD_START)&&StringUtils.contains(text,TEXT_BLOD_END)){XWPFRun xwpfRun = paragraph.getRuns().get(0);List<XWPFRun> handlerRuns = new ArrayList<>();for (int i=0; i<blodTextArray.length;i++).......}else{RuleBookmark ruleBookMark = bookmarks.getRuleBookMark(name);replaceTextBookmarks(bookmark, paragraph,text,name,ruleBookMark,textColor);}}clean code:public void replaceTextBookmarks(CTBookmark bookmark, XWPFParagraph paragraph, Bookmarks bookmarks) {String name = bookmark.getName();String text = bookmarks.getRuleBookmarkValue(name);int index = bookmarks.getIndex(name);boolean exitblodStartAndBlodend= StringUtils.contains(text,TEXT_BLOD_START)&&StringUtils.contains(text,TEXT_BLOD_END);if (StringUtils.contains(text,"\n")){dealEnterBookmark(bookmarks, bookmark, paragraph, name, text, textColor, index);return;}if(exitblodStartAndBlodend){dealCopyRows(bookmark, paragraph, name, text, textColor, index);return;}RuleBookmark ruleBookMark = bookmarks.getRuleBookMark(name);replaceTextBookmarks(bookmark, paragraph,text,name,ruleBookMark,textColor);}

原来是将这两个判断的代码块中直接编写处理代码,现在是将其写在函数中。

2、只做一件事

  • 函数应该做一件事
    上个事例中的函数的目的是用文本替换书签,但是却将不同情况的文本处理都写在一个函数中,导致函数看起来过于臃肿,可读性差;所以要判断一个函数是否只做了一件事,就是看能否再拆出来一个函数。

3、每个函数一个抽象层级

什么是抽象层级???我举个栗子

鸟{游禽{天鹅{...}鸳鸯{...}...}陆禽{孔雀{...}松鸡{...}...}鸣禽{画眉{...}黄鹂{...}...}...
}

在这个例子中,鸟是最高的抽象层级,下一层为游禽,陆禽,鸣禽等,再下一层为画眉,鸳鸯,孔雀等等
把这个例子映射到代码中,将一段代码相对照,查看一下你的代码有没有将不同的抽象层级混在一起,
如果有,就将其摘出 ,放在同一层级,这样,代码的整洁度会大大的提升,整个代码的逻辑也会更加清晰

举个栗子:

bad code :if(CollectionUtils.isNotEmpty(ruleBookmarks)){//获取相同规则书签Map<String, List<String>> ruleMap = new HashMap<>();for(RuleBookmark ruleBookmark : ruleBookmarks){String rulrCode = ruleBookmark.getRuleCode();String bookName = ruleBookmark.getBookmark();if(ruleMap.containsKey(rulrCode)){ruleMap.get(rulrCode).add(bookName);continue;}List<String> bookNameList = new ArrayList<>();bookNameList.add(bookName);ruleMap.put(rulrCode, bookNameList);}//获取审判人员、书记员姓名最大长度规则DealRuleRun.prepareRuleLimit(ruleMap, bookmarks);}
clean code:if(CollectionUtils.isNotEmpty(ruleBookmarks)){//获取审判人员、书记员姓名最大长度规则DealRuleRun.prepareRuleLimit(ruleMap, bookmarks);}public static void prepareRuleLimit(List<RuleBookmark> ruleBookmarks, Bookmarks bookmarks){Map<String, List<String>> ruleMap = getSameCodeRuleMap(ruleBookmarks);for (Map.Entry<String, List<String>> entry : ruleMap.entrySet()) {IRuleRunService iRuleRunService = chooseRuleRunervice(entry.getKey());if(iRuleRunService != null){iRuleRunService.prepareRuleLimit(entry.getValue(), bookmarks);}}}

4、使用描述性的名称

  • 其实和变量的命名基本一致,就是要描述清楚函数的功能,然而函数越短小、功能越集中,就越便于起个好名字,所以当你为起名感到困惑时就要好好想一想该函数到底要做一件什么事了。
  • 不要害怕长名称,长而具有描述性的名称,要比短而令人费解的名称好。
boolean existTagAndBookmarks = false;

虽然变量名长 但是可以通过名字就知道这个变量代表的含义是 书签和标签同时存在的状态

5、函数参数

  • 有足够特殊的理由才能用三个以上参数(多参数函数),如果函数需要三个以上参数,说明其中一些参数可能要封装为类了。

6、使用异常代替返回错误码

首先,要明确一点的是,错误码和异常,这两者在程序的表达能力上是等价的。它们都可以向调用者传达“与常规情况不一样的状态”。
返回错误码会要求调用者立刻处理错误,可能引起深层次的嵌套结构:

bad code :if (deletePate(page) == E_OK) {if (xxx() == E_OK) {if (yyy() == E_OK) {log(A);} else {log(B);}} else {log(C);}} else {log(D);}
clean code:try {deletePage();xxx();yyy();}catch (ExceptionD e) {log(D)}catch (ExceptionC e) {log(C)}catch (ExceptionB e) {log(B)}log(A)

返回错误码的方式,使得调用方必须对返回值进行判断,并作相应的处理。这里的处理行为,大部份情况下只是打一下日志,并且我们必须在每一层都记下日志以形成日志栈,这样才便于追查问题。
而采用异常的方式,只管写出常规情况下的逻辑就可以了,一旦出现异常情况,语言系统会接管自下而上传递信息的过程。我们不用在每一层调用都进行判断处理,最上层的调用方很容易就可以获得本次的调用栈,把该调用栈记录下来就可以了。因此,使用异常代替错误码,可以使得代码更清晰,可读性更好。而且有些方法是void的无返回值的。

但是这个建议并不是在所有地方都适合,比如:

  • 代码中不存在异常,只是从业务上判断这种情况是不对的,这事没必要去使用,只有在真正异常的时候,才使用异常,例:检索数据时,对应某一不存在相应的记录的情况。这时使用错误码。这种情况要明确告诉调用方,并不是系统出异常了,而是数据确实不存在,请作出相应的处理。

  • 还有最常见的NullPointerException,判断非空这种操作是必须的,不能在外面套个try catch(NullPoint…)来替代基本判断。
    也可以使用Java8中的Optional

Optional.ofNullable(param).orElse(StringUtils.EMPTY);

Optional并不能解决NullPointerException问题,但是它可以让Optional变量的使用者明确的知道这个变量中有可能不存在的值。这样就会强迫调用者去考虑,如果没有值自己应该怎么去处理。

7、抽离Try/Catch代码块

try/catch代码块处理过多,所以最好把try和catch代码块的主体抽离出来,单独形成函数

bad code:try {deletePage();xxx();yyy();} catch (Exception e) {log();}
clean code :try {do();} catch (Exception e) {log();}

三、注释

代码移动和更改:代码块移动到其他地方,而注释不随着移动,就会成为一个问题!
要牢记,带有一点注释并且整洁和有表现力的代码,要远远好过复杂并带有大量注释的代码。不要浪费时间去解释你写的代码,而去投入时间去使其整洁。

1、好注释

在这些场景下,使用注释比较好:

  • 弥补代码表达意图的失败

代码本身无法说明意图,这时使用注释,说明这段代码需要被修改

  • 提供信息

提供代码以外的信息,比如产品相关信息

  • 复杂实现的 简要概括

让阅读者快速了解某个复杂的系统

  • 警示、提醒

比如某个不起眼的代码是为了解决某个 bug,防止别人误删

  • TODO

IDE可以定位 TODO 注释,我们需要定期查看这些注释,删除不再需要的,让代码整洁(定位TODO快捷键 Alt+6)

2、坏注释

  • 令人费解的注释

读懂花费的时间比看代码的时间还长,差评

  • 误导性注释,老旧的注释

代码才是真相,注释有可能是谎言,还是要”少写注释!“

  • 日志型注释

比如记录修改日志,放到 git commit 日志里吧

  • 注释掉的代码

没用的代码及时删除

别给糟糕的代码写注释,重构!

代码整洁之道 1-3阅读笔记相关推荐

  1. 代码整洁之道 Clean Code 读书笔记

    目录 代码整洁之道 Clean Code 第一章 整洁代码 第二 三章 命名与函数 第四 五章注释与格式 第六章 对象和数据结构 第七章 错误处理 第八章 边界 第九章 单元测试 第十章 类 第十一章 ...

  2. java代码整洁之道_【读书笔记】代码整洁之道

    第一章 整洁代码 赶上期限的唯一方法:始终尽可能保持代码整洁. 整洁的代码只做好一件事. 整本书的主旨,不要重复代码,只做一件事,表达力,小规模抽象. 要想干得快,要想快点做完,要想轻松写代码,先让代 ...

  3. 什么是好代码-代码整洁之道阅读笔记

    根据我所阅读的书<代码整洁之道>里的一句话: "衡量代码质量的唯一有效标准: WTF/min" 从哲学的角度讲,不得不说这真的很客观!!! 毕业不久的我也没有太多关于好 ...

  4. 《代码整洁之道》阅读笔记 4注释

    "Comments Do Not Make Up for Bad Code."(注释不是对劣质代码的补救).事实上好的代码即便没有注释也拥有良好的可读性,但恰当的注释会让代码变得更 ...

  5. 《代码整洁之道》阅读笔记 12迭进

    系统的迭代式演进 1.通过迭进设计达到整洁目的 运行所有测试 不可重复 表达程序员的意图 尽可能减少类和方法的数量 以上规则按其重要程序排列 2.简单设计原则1:运行所有测试 设计必须制造出如预期一般 ...

  6. 《代码整洁之道》(Clean Code)- 读书笔记

    一.关于Bob大叔的Clean Code <代码整洁之道>主要讲述了一系列行之有效的整洁代码操作实践.软件质量,不但依赖于架构及项目管理,而且与代码质量紧密相关.这一点,无论是敏捷开发流派 ...

  7. 代码整洁之道(Clean Code)- 读书笔记

    Sorry, 许久未更新文章了,主要因为刚刚换了一家新公司,忙于组建团队(建设.招聘.流程.框架等)与熟悉公司业务,还有领导给的其他工作等等,实在是没有时间更新了.最近在和团队分享Bob大叔的< ...

  8. 《代码整洁之道 Clean Architecture》-读书笔记

    大家好,我是烤鸭: 关于<代码整洁之道>,记录一下读书笔记. 代码整洁之道 第一章 整洁代码 整洁代码的艺术 第二章 有意义的命名 避免误导 有意义的区分 使用读得出来和可搜索的名字 避免 ...

  9. 《代码整洁之道》细节之中自有天地,整洁成就卓越代码 读书笔记

    <代码整洁之道>细节之中自有天地,整洁成就卓越代码 读书笔记 There are only two hard things in Computer Science: cache inval ...

  10. [读书笔记] 代码整洁之道

    书的示例是Java语言编写的,虽说不会影响阅读,但是后面几章讲应用这套方法论的时候,大篇幅的Java代码分析还是挺难受的,而且连java测试框架Junit都要细讲,对于非Java系的开发者来说,一些内 ...

最新文章

  1. Request.ServerVariables参数集
  2. 【C++】C/C++ 中的单例模式
  3. 履带机器人运动控制器c++_敏捷得像猫,被抛出后能平稳着地,有意思的美国西点军校机器人!...
  4. StringBuffer、StringBuilder区别以及Synchronized原理
  5. 群晖系统挂载NTFS硬盘
  6. VTK修炼之道13:数据读写_图像数据的读写
  7. svn服务器创建分支原理,svn 创建分支、合并分支、以及报错处理
  8. [html] const nums1 = [1, 2, 2, 1], nums2 = [2] 交集是什么?
  9. 高一计算机网络技术应用计划,高一计算机网络应用基础教学计划
  10. 学习笔记-java编程-交通灯管理器设计流程。
  11. 限制UI只能在屏幕内移动(放大或缩小屏幕同样适用)
  12. 在线JSon格式显示工具
  13. Balancing Act(树的重心入门)
  14. ORACLE常用系统查询
  15. 手游开发之lua的class函数详解
  16. Vs自带的freetextbox无法在远端使用
  17. css 剪辑图片_[译]用CSS剪切圆形图片
  18. 如何读SPD 信息...(转自英布之剑的博客)
  19. 深蓝色固体Cyanine5-Azide,Cy5-N3,Cy5 Azide,菁染料CY5叠氮
  20. Vue项目对接微信公众号踩坑日记

热门文章

  1. “菩提本无树,明镜亦非台,本来无一物,何处惹尘埃”的典故
  2. Apache Log4j2 漏洞解决办法
  3. vscode插件不兼容无法安装
  4. 导弹发射-河南省第九届省赛D题
  5. CVE-2012-0158漏洞分析
  6. EDA程序设计--数字日历电路
  7. 小白学 Python(1):开篇
  8. UEFI EDK2 遇到的问题集合
  9. H-1B visa - H-1B 签证
  10. undefined control sequence_control两个超级实用的短语解析