代码编写的参考规则-方法篇

代码编写的参考规则-方法篇

  简言:在写代码的过程中,我总是会遇到一些复杂的业务,在编写代码时逻辑清晰,一个方法足以写完。但写完后阅读、维护和修改代码时,会很难寻找到相应的代码并修改。这说明我的代码可读性比较低,遵循这些规范,我的代码可读性大大提高了。所以我想分享给更多有这个疑惑的人,如果有什么更好的规则方法,欢迎随时讨论。

1.短小

  每个方法应该只有两三行、四行长,并且每个方法一目了然,都只做一件事,并且每个方法都依序把你带到下一个方法。
代码块和缩进,判断语句中的代码应该只有一行,(前提是方法的名称具有说明性的描述)。所以,方法的缩进层级不该多于1层或者2层,这样的方法易于阅读和理解,不但能保持方法短小,还能增加文档价值。

2.只做一件事

  方法应该做一件事,做好这件事,只做这一件事。 编写方法是为了把大概念拆分为另一个抽象层上的一系列步骤。所以方法是否是只做了一件事,就看该方法内的代码是否是同一抽象层的。还有一个方法就是看看能否再拆出一个方法,该方法不仅只是单纯地重新诠释其实现。

3.每个方法一个抽象层级(写方法的思维重点)

  方法中混杂不同抽象层级,往往让人迷惑。读者可能无法判断某个表达式是基础概念还是细节。一旦细节与基础概念混杂,更多的细节就会在方法中纠缠起来。

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

  我们想要让每个方法后面都跟着位于下一抽象层级的方法,这样在查看方法列表时,就可以跟着抽象的层级向下阅读了,这就叫向下规则。
例:最高层:今天要炒菜做饭。下一层:做饭要先煮饭再炒菜。下一层:煮饭要先打米淘米再放进电饭锅,炒菜要切菜开火烧油再翻炒。。。。。。
  不过程序员往往很难遵循这条规则,但是这是保持方法短小,确保只做一件事的要诀,让代码读起来是一系列自顶向下的内容。

4.switch语句

  写出短小switch语句很难(包括ifelse),需要确保每个switch都埋藏在较低的抽象层级,并且永不重复。但我们可以利用多态来实现这一点,例如将switch埋藏在抽象工厂下,使用接口多态的接收调用。

5.使用描述性的名称

  方法越短小,功能越集中,就越便于取个好名字。
  好处:能理清你关于模块的设计思路,并帮你改进。命名方式需要保持一致,使用与模块名一脉相承的短语、名词和动词给方法命名。

5.1 别害怕长名称

  长而具有描述性的名称,比短而令人费解的名称好。比描述性长注释好。

5.2 别害怕花时间取名字

  尝试不同名称,去测试阅读效果,找到最具有描述性的那一个为止。

6.方法的输入参数

  方法的输入参数越少越好,应该尽量避免三个及其以上的参数,除非有足够特殊的理由。
  原因:参数概念太多,每次看都需要翻译,并且会导致更难测试。

  6.1 一元方法的普遍形式(传入单个参数)

  向方法传入单个参数,有两种极普遍的理由:一是 是否存在,二是将参数转换为其他类型。还有一种虽然不普遍但是非常有用的单参数方法形式,那就是事件(event)。
  这种形式中,有输入参数但是没有输出参数。程序将方法看作是一个事件。(使用时应该小心,让读者清楚的了解它是一个事件,谨慎选用名称和语境)

  6.2 布尔值输入参数

  一个方法的入参如果是一个布尔值,会导致代码的可读性大大降低。
  解决方法:拆解为两个方法,true时一个方法,false时一个方法。

  6.3 二元方法

  有两个参数的方法比一元方法难懂,重点体现在两个参数存在排序问题,并且会存在传递的参数你需要忽略掉才能看明白的情况(比如传入OutputStream对象)所以可以想办法将二元方法转换为一元方法。

  6.4 三元方法

  排序,思考,忽略的问题都会加倍体现。

  6.5 参数对象

  如果方法看来需要两个,三个以上的参数,那就说明有些参数应该封装为类了。

  6.6 参数列表

  有时,我们需要传入数量可变的参数集合(Object… args),其实这也只算是一个参数,相当于是传递的是一个列表。

  setNameList(Object... args) 相当于 setNameList(List<Object> argList)
  6.7 动词与关键字

  给方法起个好名字,能较好解释方法意图,以及参数的顺序和意图,对于一元方法,方法和参数应该形成好的动词/名词对形式 。

  比如 writeField(name); 他告诉我们这个name要被写,并且这个name是一个Field

7.尽量避免使用输出参数

  有些偶然的时序性耦合以及顺序依赖,导致有参数或全局变量的改变不会达到我们预期,这都是违反方法只做一件事的原则而导致的。
输出参数:普遍而言,应该避免使用输出参数,因为面向对象语言中,对输出参数的大部分需求已经消失了。如果方法必须要修改某种状态,就修改所属对象的状态吧。

8.将业务与IF分开

  方法要么做什么事,要么回答什么事,如果两者情况一起做,就会导致混乱。
  比如一个方法如果设置成功就返回true,这样会导致读起来会让人容易误解,应该分开为是否设置成功和设置两个方法。

9.使用异常替代返回错误码

  如果从指令式方法返回错误码,会导致更深层次的嵌套结构,使用异常来代替返回错误码,错误处理代码就能从主代码中分离出来,得到简化。

  9.1 try/catch代码的代码块需要抽离

  最好把try和catch代码块的主体部分抽离出来,另外形成方法,这样看起来会更美观,利于理解和修改。

  9.2 错误处理只处理错误

  方法应该只做一件事,而错误处理就是一件事,因此处理错误的方法前后都不该做其他事。

  9.3 error.java 依赖磁铁

  如果使用某个类或者是枚举来定义所有错误码,修改后会导致其他类都需要重新编译和部署,这样的类就是一块依赖磁铁,如果使用异常来代替错误码,新异常就可以从异常类派生出来,无需重新编译或部署。

10.消除重复(DRY原则)

  消除掉重复的代码,会让整个模块的可读性因为重复的消除而得到提升。自从子程序发明以来,软件开发领域的所有创新都是在不断尝试去消灭重复代码。

11.写在最后

  1.不要担心写不出这样的好代码,千里之行始于足下,先去做,再去打磨,渐渐就会变成这样的代码,连uncle Bob都做不到一次到位,你为什么纠结呢。
  2.编程艺术是且一直是语言设计的艺术。大师级程序员把系统当故事来讲,而不是当做程序来写,所以写方法时可以多用一下故事的思路去想方法实现,可能对你有帮助哦。
  3.我是喵煞,如果文章对你有帮助的话可以点赞收藏哦。(关注也可以点一下的其实)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值