###一、前言
在实际工作中,我们所编写的代码主要是给我们自己看的,只是顺便让机器去执行。那么,可想而知,良好的代码编写风格,将给维护人员带来很大的便利之处。这篇文章是我工作中的一些总结,也许并不适合你,但值得参考,因为我的很多同事并没有良好的编码风格和习惯,每次我看他们代码时,说句实话,我想吐。如果你有更好的建议,欢迎留言告知。(注:本文以Java语言为例)
###二、这是正文
编码方面
1) 方法名称的意义要明确。
在提供方法时,一定要明确方法的用意,不然,他人在看到这个方法时会有歧义,以为用错了。
例如:
我想根据no获取大于no的所有数据,而如下的方法其实是获取等于no的意思,而不是大于no的,因此会带来歧义。(我之前就犯过这样的错误 😦)
// 不友好的定义
public List<Book> getBookListByNo(int no);
// 友好的定义
public List<Book> getBookListByGtNo(int no);
注意:
Gt 是greater than 的缩写,因此不会带来歧义。在NoSQL数据库,比如MongoDB的条件查询中就是这样命名的,如下:
- (>) 大于 ->$gt
- (<) 小于 -> $lt
- (>=) 大于等于 -> $gte
- (<= ) 小于等于 -> $lte
2) 可根据参数顺序定义方法名。
在给方法提供参数时,方法的命名最好根据参数列表进行命名,这样调用者通过方法即可看到参数的调用顺序,而不必进入方法内查看参数列表,但此规则仅仅适用于参数较少的方法。
例如:
我想通过故事ID和用户ID去获取单个故事或者列表,给定故事ID和用户ID都是long型。
// 不友好的定义
public Story getStoryId(Long uid,Long storyId);
public Story getStoryBySidAndUid(Long uid,Long sid);
// 友好的定义
public Story getStoryByUidAndSid(Long uid,Long sid);
解析:
如果调用方法时没有注意参数的顺序,很容易导致用错,特别是对于参数类型都一样的参数列表,编译器不会报错,将造成严重的后果。如果程序员们都按照这个规则对短参数列表进行这样的命名,注释都省得写了,错误发生的概率也就小了。
3)不返回给客户端映射数据库的实体类。
在给客户端做接口时,返回的数据字段一定要是一个自定义的类,如果返回的结果直接是映射数据库的类,那么这将是灾难。在客户端需要增加返回字段时,你不得不在重新开一个新的接口。虽然有注解可以忽略掉让dao层不识别扩展的字段,但对于客户端变化如此之快的业务,这样做也不是明智之举,也会使得原始类变得臃肿,难以维护。(这个只有做过api接口和客户端对接的业务才会有深深的体会)
4) 能用包装类型时坚决不用基本类型。
在定义的bean时,基本类型最好使用包装类,而数组最好使用List,因为List可以使用Java的一些新特性,用起来更方便,也能给他人提供很好的调用,除此之外,对List的操作要比操作数组安全得多,当然,这么做有不好之处,出现空指针的概率变大了,编码时要时刻注意。同时,有时候数据库的查询结果可能是 null,因为自动拆箱,用基本数据类型接收有 NPE 风险。(好处还不止这些)
// 不友好的定义
public class TestClass{
privete long id;
private String name;
private int age;
private int[] hobbies;
// 省略构造方法、getter、setter、toString方法
}
// 友好的定义
public class TestClass{
privete Long id;
private String name;
private Int age;
private List<Integer> hobbies;
// 省略构造方法、getter、setter、toString方法
}
5)杜绝if else的层层嵌套。
在编码过程中,如果能够使用反向条件过滤的逻辑,就先过滤掉,这样可以避免if else结构的层层嵌套,使得代码看起来层次结构非常的清晰易懂,也便于维护。如下代码块,你更喜欢看哪块代码呢?
// 不友好的代码
public StringBuilder testMethod(HttpServletRequest request, Long commentsId){
StringBuilder rst;
if (commentsId == null || commentsId <= 0) {
rst = ApiResBuilder.json(ActionStatus.PARAMAS_ERROR.inValue(), "invalid-comments_id");
} else {
CommentsBean comment = commentsService.get(commentsId);
if (comment == null) {
rst = ApiResBuilder.json(CommunityActionStatus.COMMENTS_NOT_EXISTS);
} else {
long uid = (Long) request.getAttribute(APIkey.uid);
if (commentsService.praise(uid, commentsId, comment.getReply2thread())) {
rst = ApiResBuilder.json(ActionStatus.NORMAL_RETURNED);
} else {
rst = ApiResBuilder.json(ActionStatus.UNKNOWN);
}
}
}
return rst;
}
// 友好的代码
public StringBuilder testMethod(HttpServletRequest request, Long commentsId) {
if (Objects.isNull(commentsId) || commentsId <= 0) {
return ApiResBuilder.json(ActionStatus.PARAMAS_ERROR.inValue(), "invalid-comments_id");
}
CommentsBean comment = commentsService.get(commentsId);
if (comment == null) {
return ApiResBuilder.json(CommunityActionStatus.COMMENTS_NOT_EXISTS);
}
long uid = (Long) request.getAttribute(APIkey.uid);
if (commentsService.praise(uid, commentsId, comment.getReply2thread())) {
return ApiResBuilder.json(ActionStatus.NORMAL_RETURNED);
}
return ApiResBuilder.json(ActionStatus.UNKNOWN);
}
6) 不要为了省事,编写较