美文网首页
聊聊代码注释

聊聊代码注释

作者: 键盘男 | 来源:发表于2019-05-12 22:22 被阅读0次

当我们谈起代码注释,估计你有以下反应:

1.老子的代码没别人看,不需要注释;
2.这段代码很简单,不需要注释;
3.这段代码很复杂,我多写些注释;

当你发现一段代码有bug,或者看到一坨很恶心的代码像重构,然而没有一点注释,可能会出现以下心理活动:

1.写这段代码的家伙(有可能是你自己)一点注释都不写,这bug怎么修?
2.这段代码做什么?需求是什么?找找需求文档...
3.参数啥意思?我找找接口文档先...
4.需求文档呢?接口文档呢?(好旧的需求)

当你发现一段代码有bug,还有注释:

1.幸好有注释,我知道它干什么;
2.草,注释说的跟代码不符合呀!

今天咱们聊聊,没写注释和写了注释也会出现的尴尬的问题。


请求api的注释

1.如果你公司有接口文档,你应该写注释;
2.如果你公司没接口文档,你更应该写注释。

举个的例子:


public interface Api {
    @POST("/challenge/createActivity")
    Observable<String> createActivity(@Field("activityStartTime") int activityStartTime, @Field("activityEndTime") int activityEndTime,
                                      @Field("challengePoint") int challengePoint,
                                      @Field("checkInNumRule") int checkInNumRule,
                                      @Field("description") String description,
                                      @Field("distanceRule") int distanceRule,
                                      @Field("speedRule") int speedRule,
                                      @Field("sumDistanceRule") int sumDistanceRule,
                                      @Field("taskType") int taskType);
}

你知道createActivity方法是做什么的吗?直译的话,可以认为这是“创建一个活动”的接口。你知道每个参数含义吗?distanceRule checkInNumRule什么意思?反正没注释笔者是不知道。

这时,有工程师会:

安卓工程师:“找接口文档。”
笔者:“请问接口文档在哪?”
安卓工程师:“公司一般有接口文档管理网站,搜一下就好。”

“搜接口文档”看起来很简单的事,实际上,有那么简单吗?对于新项目,接口文档很好找,如果是老项目,接口文档管理网站可能已经换了,你还得问后端同事,旧网站网址。而且不是每个后端工程师都知道网址,可能得问老员工......

还有,如果每次阅读这段代码,都要查查接口文档,耗费工程师多少时间成本?

以下是笔者认为比较好的注释:


public interface Api {

    /**
     * 创建个人发起的挑战活动  http://doc.thejoyrun.com/api/challenge/createActivityForPersonal
     *
     * @param activityStartTime 挑战开始时间
     * @param activityEndTime   挑战结束时间
     * @param challengePoint    挑战积分
     * @param checkInNumRule    打卡次数, 当taskType=2时,必填
     * @param description       规则说明
     * @param distanceRule      单次打卡距离, 当taskType=2时,必填
     * @param speedRule         配速, 当taskType=1时,必填,整型,如配速 6分30秒,应传390
     * @param sumDistanceRule   累计距离, 当taskType=1时,必填
     * @param taskType          挑战类型, 1是累计距离挑战;2是打卡挑战;必填
     *
     * @return 创建成功返回msg
     */
    @POST("/challenge/createActivity")
    Observable<String> createActivity(@Field("activityStartTime") int activityStartTime, @Field("activityEndTime") int activityEndTime,
                                      @Field("challengePoint") int challengePoint,
                                      @Field("checkInNumRule") int checkInNumRule,
                                      @Field("description") String description,
                                      @Field("distanceRule") int distanceRule,
                                      @Field("speedRule") int speedRule,
                                      @Field("sumDistanceRule") int sumDistanceRule,
                                      @Field("taskType") int taskType);
}

这样是不是清晰多了?方法功能、参数意义、接口文档网址都有了。工程师还能用Quick Documentation快速查看代码注释,节省工程师多少时间。


以下给出接口文档 (假的url):http://doc.thejoyrun.com/api/challenge/createActivityForPersonal

接口名称 创建个人发起的挑战活动-(预设)
请求类型 post
请求Url  /challenge/createActivity
变量名 含义 类型 备注
activityEndTime 挑战结束时间 number 必填
activityStartTime 挑战开始时间 number 必填
challengePoint 挑战积分 number 必填
checkInNumRule 打卡次数 number 当taskType=2时,必填
description 规则说明 string 必填
distanceRule 单次打卡距离 number 当taskType=2时,必填
speedRule 配速 number 当taskType=1时,必填,整型,如配速 6分30秒,应传390
sumDistanceRule 累计距离 number 当taskType=1时,必填
taskType 挑战类型 number 1是累计距离挑战;2是打卡挑战;必填

自动生成代码/注释

一份标准的文档,是有固定格式,笔者公司用RAP文档管理。笔者写了个用java代码根据文档生产代码+注释的小工具,繁琐、重复的工作,交给脚本生成就好。


Java Bean注释

1.当成员变量英文名或意义比较复杂,必写注释;
2.当成员变量数值有范围,或多个值且有特定意义,必写注释。

请看请求接口和返回列表

public interface Api {
    /**
     * 我的挑战列表   http://doc.thejoyrun.com/api/challenge/myChallenges
     */
    @GET("/challenge/myChallenges")
    Observable<List<Challenge>> getChallengeList();
}
/**
 * 挑战
*/
public class Challenge {
    int    challengeId;    
    String title;
    String imageCover;

    int activityEndTime;
    int activityStartTime;
    int activityStatus;
    int joinTime;
    int timeLeft;
    int userJoinStatus;
}

Challenge是挑战列表的元素。直译,猜到activityStatususerJoinStatus是两种状态,但这两种状态分别有什么数值呢?什么数值代表什么意思?

当你看到如下代码:

Challenge challenge = new Challenge();

switch (challenge.getActivityStatus()){
     case 0:
          // do something A
          break;
     case 1:
          // do something B
          break;
    ......
}

假如,测试工程师跟你说 活动进行中有bug,而你又不知道activityStatus哪种情况会执行AB,那你就必须debug,或者查接口文档activityStatus哪个数值是 活动进行中

还有,timeLeft直译“剩下的时间” ,是到哪个时间节点剩下的时间?

这些工作都会大量耗费工程师时间。如果我们把注释写好一点:

public class Challenge {
    /** 挑战活动ID */
    int    challengeId;
    /** 标题 */
    String title;
    /** 封面地址 */
    String imageCover;

    /** 挑战结束时间 */
    int activityEndTime;
    /** 挑战开始时间 */
    int activityStartTime;
    /**
     * 挑战活动状态 0-未开始 1-进行中 2-已结束
     */
    int activityStatus;
    /** 用户报名挑战时间 */
    int joinTime;
    /** 挑战未开始的时候为距离开始的剩余时间;当挑战进行中的时候表示还剩余多少时间结束 */
    int timeLeft;
    /**
     * 参与状态 -1失败 0-未参加 1-挑战中 2-挑战成功
     */
    int userJoinStatus;
}

这样就清晰多了,直接Quick Documentation就可以查看activityStatus注释。你可以明确activityStatus==1时,才出现bug,直接定位到case 1出bug代码块。

还有,timeLeft在不同状态下,意义不同。1.挑战未开始,为距离开始的剩余时间;2.挑战进行中,表示还剩余多少时间结束。如果不写注释,谁知道这些啊?


Activity注释

如果给你一个Activity,完全没有注释:

@RouterActivity("page_x")
public class ActivityX extends AppCompatActivity {
        ......
}

Activity注解@RouterActivity表示外部可以通过page_x路由跳进来。

请问,这个Activity是从哪个界面跳进来的?

好运的话,Find Usages会找到startActivity(new Intent(context, ActivityX.class)),或者找到路由跳转page_x的位置。

给你个场景:ActivityXA界面条进来,而A界面必须满足一定条件,才出现跳转page_x按钮。例如,A界面请求服务器,返回某个字段status=1满足条件。

再复杂一点,跳转路径:

C -> B -> A -> X

继续复杂点,page_x是后端返回的跳转路径,app不写死。在代码层面根本找不到入口。

你能一眼看出ActivityX是干什么的吗?

对于复杂的跳转路径,及满足条件才能跳转,我们非常难知道ActivityX的功能是什么。

如果我们在头部写上备注:

/**
 * 参与过的活动详情。<br>
 * 入口:我的活动,右上角“历史” -> 参与过的活动列表,点击item进入
 */
@RouterActivity("page_x")
public class ActivityX extends AppCompatActivity {
        ......
}

这样是不是清晰明了?


结语

本篇笔者就重点说了请求接口注释、java bean注释。读者应该举一反三:

1.java的方法要写注释,表明用途;
2.方法参数写注释,表明意义;
3.成员变量写注释,表明意义,数值范围,每个值的意义等.

每次笔者要修bug,当代码不是笔者写,而且又没有任何备注,恐怕会立即脱口而出“卧槽”!
写好注释不能让你从中级变高级工程师,但其他工程师阅读你的代码,知道你是一个做事谨慎细心的人,也让阅读的人赏心悦目。

不写注释有个笑话:

我写这段代码时,知道它在做什么的,只有老天和我;
但是现在,只有老天知道这段代码在做什么。

相关文章

网友评论

      本文标题:聊聊代码注释

      本文链接:https://www.haomeiwen.com/subject/kdjfaqtx.html