`
zhang_xzhi_xjtu
  • 浏览: 538309 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

实践中的重构23_详尽的注释未必是好注释

OOP 
阅读更多
注释一直是软件开发中的一个老大难问题。
代码中一个注释都没有是一种常见情况,给后来的开发维护带来巨大的成本。
代码中注释零零散散也是一种常见情况,这个依赖于程序员,有的程序员自觉的写上注释,有的觉得无所谓,干脆不写,有的在该写的地方写,不该写的地方省略,有的在不该写的地方写,该写的地方留白让后人抓狂。
系统大了,代码多了,公司一般都会出台一些强制性的代码规范,规范中自然少不了注释规范。于是,程序员为了满足代码注释规范,辛辛苦苦的添加了满屏的注释。
而实际上这种出发点是为了满足规范的注释是少有人看,也少有被看的价值。大家的关注点是在有没有注释上,而不是在注释的质量上。因为该注释被加上去的原因是规范需要,而不是代码或者程序员需要。这样的注释自然就少有人去精心维护。越是少有人去维护,注释和代码就越脱节,于是注释的价值随着时间的推移就更小了,一个恶性循环就这样华丽的诞生了。
有的注释为了满足规范写的很详尽,以为这样的注释就是好的注释。殊不知注释和代码一样,也是有质量的,也一样有可能散发一些不好的味道。
且看下面一个类的方法注释。
/**
 * 上传文件帮助类。
 * */
public class FillUploadHelper {

	/**
	 * 得到一个用户上传文件的文件路径。
	 * 
	 * <pre>
	 * 用户上传文件的文件路径为:
	 * 最高一级目录\年月\年月日\用户userId的8-10位\5-7位\2-4位\文件名。
	 * 例如一个用户的id为0123456789,文件上传的日期为20110103,文件名为"allen.txt",则上传文件的文件路径为:
	 * 最高一级目录\201101\20110103\789\456\123\allen.txt。
	 * </pre>
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @param date
	 *            上传文件的时间 yyyymmdd格式。
	 * @param fileName
	 *            文件名。
	 * 
	 * */
	public String getFilePath(String userId, String date, String fileName) {
		return null;
	}

	/**
	 * 得到一个用户上传文件的目录。
	 * 
	 * <pre>
	 * 用户上传文件的目录为:
	 * 最高一级目录\年月\年月日\用户userId的8-10位\5-7位\2-4位。
	 * 例如一个用户的id为0123456789,文件上传的日期为20110103,则上传文件的目录为:
	 * 最高一级目录\201101\20110103\789\456\123。
	 * </pre>
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @param date
	 *            上传文件的时间 yyyymmdd格式。
	 * 
	 * */
	public String getFileDir(String userId, String date) {
		return null;
	}

	/**
	 * 得到一个用户上传文件的用户目录。
	 * 
	 * <pre>
	 * 该用户目录为:
	 * \用户userId的8-10位\5-7位\2-4位。
	 * 如userId为0123456789,则用户目录为:
	 * \789\456\123。
	 * </pre>
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @return 用户目录。
	 * */
	private String getUserDir(String userId) {
		return null;
	}

	/**
	 * 得到一个用户上传文件的日期目录。
	 * 
	 * <pre>
	 * 该日期目录为:
	 * \年月\年月日。
	 * 如日期为20110103, 则日期目录为:
	 * \201101\20110103。
	 * </pre>
	 * 
	 * @param date
	 *            上传文件的时间 yyyymmdd格式。
	 * */
	private String getDateDir(String date) {
		return null;
	}

	/**
	 * 得到用户上传文件的最高一级目录。
	 * 
	 * @return 用户上传文件的最高一级目录。
	 * */
	private String getUploadDir() {
		return null;
	}
}

可以说这个注释已经很详尽了,每个方法都详尽的注释了上传文件的路径名的相关信息。
但是同代码一样,这段注释是有些不好的味道的。
方法注释中有重复的片段,而重复的注释意味着如果上传文件的目录规则改变的话,一大堆方法的注释都要改动。重复总是不好的。
OOP的最小构建单位是类,而不是方法。这句话不仅适用于领域对象,一样适用于工具类。通过抽取方法级别的详尽注释到类上,集中上传文件的目录规则,从而减少重复。
/**
 * 上传文件帮助类。
 * 
 * <pre>
 * 
 * 用户上传文件的文件路径分为4部分。
 * 
 * 系统配置的最高一级目录。uploadDir。
 * 用户上传文件的日期目录dateDir,格式为\年月\年月日。
 * 用户上传文件的用户目录userDir,格式为\用户userId的8-10位\5-7位\2-4位。
 * 用户上传文件的文件名。fileName。
 * 
 * 例如系统配置的目录为\saveUpload,一个用户的id为0123456789,
 * 文件上传的日期为20110103,文件名为"allen.txt",则上传文件的文件路径为:
 * 
 * \saveUpload\201101\20110103\789\456\123\allen.txt
 * 
 * <pre>
 * */
public class FillUploadHelper2 {

	/**
	 * 得到一个用户上传文件的文件路径。
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @param date
	 *            上传文件的时间 yyyymmdd格式
	 * @param fileName
	 *            文件名
	 * 
	 * */
	public String getFilePath(String userId, String date, String fileName) {
		return null;
	}

	/**
	 * get uploadDir+dateDir+userDir。
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @param date
	 *            上传文件的时间 yyyymmdd格式
	 * 
	 * */
	public String getFileDir(String userId, String date) {
		return null;
	}

	/**
	 * get userDir。
	 * 
	 * @param userId
	 *            用户id,10位。
	 * @return 用户目录。
	 * */
	private String getUserDir(String userId) {
		return null;
	}

	/**
	 * get dateDir。
	 * 
	 * @param date
	 *            上传文件的时间 yyyymmdd格式。
	 * */
	private String getDateDir(String date) {
		return null;
	}

	/**
	 * get uploadDir。
	 * 
	 * @return 用户上传文件的最高一级目录。
	 * */
	private String getUploadDir() {
		return null;
	}

}

分享到:
评论
19 楼 c.zhiwu 2011-03-23  
这是代码和文档的同步问题,well design 的代码远比详尽的注释好
18 楼 mtnt2008 2011-03-22  
Bruce.Sun 写道
关于注释我看了许多,我发现一个奇怪的问题,许多人写注释喜欢写what,但是不喜欢写why,很简单的一个列子,给一个变量赋值
a = 0,我看到过很多人的注释是“ //令a的值变为0”
但是对于我们程序员而言,很多时候这种注释对我们没什么帮助,我们更希望知道为什么要使a=0,对此修改会造成何种影响等等,至于a=0这句描述的是什么意思,我相信任何一个智商正常的人都看的明白的,也就是说这句注释是个累赘,拙见 哈哈


+1

多写为什么的注释代码
17 楼 mercyblitz 2011-03-22  
月落码农 写道
我的观点从来都是代码自注释,比如方法名,参数名,一个方法他自己应该告诉别人我是做什么的,而不是写上一段注释告诉别人我是做什么的。而且如果注释没有维护好,反而会误导别人,本来一开始你想放方法A做A,但是后来你把方法A改成去做其他了,注释没有相应的维护好,那么后面人就被你忽悠了。




对于简单的代码可以这么做,不过复杂的操作还是必须介绍一下!
16 楼 月落码农 2011-03-22  
我的观点从来都是代码自注释,比如方法名,参数名,一个方法他自己应该告诉别人我是做什么的,而不是写上一段注释告诉别人我是做什么的。而且如果注释没有维护好,反而会误导别人,本来一开始你想放方法A做A,但是后来你把方法A改成去做其他了,注释没有相应的维护好,那么后面人就被你忽悠了。
15 楼 yangguo 2011-03-22  
少写注释,多写自解释的代码。

14 楼 Bruce.Sun 2011-03-22  
关于注释我看了许多,我发现一个奇怪的问题,许多人写注释喜欢写what,但是不喜欢写why,很简单的一个列子,给一个变量赋值
a = 0,我看到过很多人的注释是“ //令a的值变为0”
但是对于我们程序员而言,很多时候这种注释对我们没什么帮助,我们更希望知道为什么要使a=0,对此修改会造成何种影响等等,至于a=0这句描述的是什么意思,我相信任何一个智商正常的人都看的明白的,也就是说这句注释是个累赘,拙见 哈哈
13 楼 chan.d 2011-03-22  
其实注释是写给别人看,也是写给自己看。
12 楼 dsjt 2011-03-22  
见过最蛋疼的注释就是:
1.在构造方法上加注释:
/**
* 无参构造方法
*/

/**
* 有参构造方法
*/



2. 在setter getter上加注释:
/**
* xxx的set方法
*/
/**
* xxx的get方法
*/
11 楼 mercyblitz 2011-03-22  
这不是注释的问题,注释越简明越好,注释拖拉不是注释的问题,而是方法操作比较复杂!
10 楼 sakajiaofu 2011-03-22  
aws 写道
好的程序员写出的代码,直接看代码,看命名和逻辑和接口就会很清晰明了,不需要太多注释

没经验的程序员往往写出一堆逻辑乱七八糟,命名稀奇古怪,胡乱跳转的东西,这种加了再多注释也是枉然

同意这个观点,但是一定的注释还是有必要的
9 楼 hyj1254 2011-03-22  
引用
好的程序员写出的代码,直接看代码,看命名和逻辑和接口就会很清晰明了,不需要太多注释

恩,重构中也有这种观点,它把过多的注释也看成一种bad smell。尽量用良好的命名取代注释。
8 楼 xiaoyaosheng86 2011-03-22  
aws 写道
好的程序员写出的代码,直接看代码,看命名和逻辑和接口就会很清晰明了,不需要太多注释

没经验的程序员往往写出一堆逻辑乱七八糟,命名稀奇古怪,胡乱跳转的东西,这种加了再多注释也是枉然

赞成你的说法。你看国外那些开源代码,那命名基本上一看就知道什么意思,然后再看一下参数,应该就很清楚了。
7 楼 aws 2011-03-22  
好的程序员写出的代码,直接看代码,看命名和逻辑和接口就会很清晰明了,不需要太多注释

没经验的程序员往往写出一堆逻辑乱七八糟,命名稀奇古怪,胡乱跳转的东西,这种加了再多注释也是枉然
6 楼 xhpscdx 2011-03-21  
代码书写 ,整洁度,可读性。是看一个程序员好撇
5 楼 zhang_xzhi_xjtu 2011-03-21  
这个属于类的spec了,所以我觉得放在类里面比较好,这个类应该包含使用该类的信息。

拖来拖去的问题,我的看法是这样的,如同我们使用类库一样,首先看的是类说明,然后才看方法说明。

当然放在测试类里面也是一个选择。
4 楼 sleepinglord 2011-03-21  
测试类更好+1。

全都搁到类注释里,如果代码很长,你就得拖来拖去。
但我支持像lz那样,提供一个类的总体需求描述的方法。
3 楼 抛出异常的爱 2011-03-21  
这段注释写在对应的测试类中更好吧
而且工具放在工具类中静态化更好.

2 楼 zhang_xzhi_xjtu 2011-03-20  
多处零散的点集中到了一个,原本多处的改动只需要改动一处,这个就是进步。

规则如果小变,比如用户级目录从\789\456\123变为\89\67\45的话,改动的点是很少的。主要是把目录结构抽象成了概念而不是实现。

规则如果大变,整个类都变掉了,那么也是没有办法的。
1 楼 tenderuser 2011-03-20  
感觉想法挺好的,但是下面的代码中的注释并没有很好的解决你上面提到的问题,如果系统规则变了 , 方法上的注释还是要改的。。。并且如果你在类级别上注释太多的话,感觉也是很麻烦。。

相关推荐

Global site tag (gtag.js) - Google Analytics