为什么我不赞成在代码里加注释

21CTO社区导读:

本文来源于Quora,作者有两位,分别是MagnusFalk,有十年的开发和大型分布式系统。以及MattGodbold20余年编程经验。

关于代码里的注释,我给大家说明的观点有如下。

概述

关于注释,首先它是有用的,通常情况下都需要。但是我认为,没有注释会更好。

下面来向各位解释我的理由:

我们的目标是编码。如要有人来通读它,需要完全清晰它的作用是什么。包括名称,结构,代码背后的思维等,这些应该最大化的开放、清晰、透明。

当我自己写注释时,会遵循增加更多详细以及增进的事情。我还期待我未来会再这些代码,不希望出现迷惑。所以我主要编写注释去增强我的未来。我想我此时的代码并不怎么清晰。

这并不是说注释不好。但是想让代码开发的更清晰,这个注释可以不需要。这是因为一些时候,注释与代码的功能未必匹配。

以下是代码的几个层次:

第一层:最差

复杂。代码不透明,而且什么注释也没有。

第二层:较好

复杂,不透明的代码与注释。现在大部分现实情况的程序员都是这样。

还有的程序员这样,实在是不该。

第三层:更好

简单,透明的代码与注释。

第四层:最好

代码写得如此营养丰富,注释根本不需要。

关于编码

我们在编码时,一定要干净,清晰,绝大多数还是需要用注释。因为大多数的程序还处于前三层,第四层是我们要达到的目标。

那么,什么时候需要注释?

当代码写的功能较复杂,或者看起来不易读,请使用注释;

如果执行结果不明显时,请使用注释;

当调用的方法上下文不明显时,请使用注释;

注释也不能只写晦涩的一行,为了写明白,有时候你要像写散文一样清晰优雅,无论是中文还是英语。

代码整洁之实践

以下是代码整洁的一些具体实践,和语言无关,供大家参考。

1.如何拒绝注释,用代码来阐述注释

反例如下:

///summary///!

#$%^^*((!

#$%^^*((!

#$%^^*((!

#$%^^*((////summary///rturns/rturnspublicdcimalGtCash(){//!

#$%^^*((!

#$%^^*((vara=nwListint(){2,3,10};varb=2m;varc=0m;//!

#$%^^*((!

#$%^^*((!

#$%^^*((forach(varpina){c+=p*b;}rturnc;}重构后的代码如下:

publicdcimalCalculatTotalCash(){varitmCounts=nwListint(){2,3,10};varpric=2m;rturnitmCounts.Sum(p=p*pric);}

良好的代码命名完全可以替代注释的作用,如果你正在试图写一段注释,从某种角度来看,你正在试图写一段别人无法理解的代码。

当你无法为你的方法起一个准确的名称时,很可能你的方法不止做了一件事,违反了(Doonthing)。特别是你想在方法名中加入:And,Or,If等词时。

2.为布尔变量赋值

反例:

publicboolIsAdult(intag){boolisAdult;if(ag18){isAdult=tru;}ls{isAdult=fals;}rturnisAdult;}重构后:

publicboolIsAdult(intag){varisAdult=ag18;rturnisAdult;}

3.双重否定的条件判断

反例:

if(!isNotRmbrM){}重构后:

if(isRmbrM){}

不管你有没有见过这样的条件,反正我见过。见到这样的条件判断,我顿时就晕了。

4.拒绝HardCod,拒绝挖坑

反例:

if(carNam=="Nissan"){}重构后:

if(car==Car.Nissan){}

既然咱们玩的是强类型语言,咱就用上编译器的功能,让错误发生在编译阶段

5.拒绝魔数,拒绝挖坑

反例:

if(ag18){}重构后:

constintadultAg=18;if(agadultAg){}

所谓魔数(Magicnumbr)就是一个魔法数字,读者完全弄不明白你这个数字是什么,这样的代码平时见的多了

6.复杂的条件判断

反例:

if(job.JobStat==JobStat.Nw

job.JobStat==JobStat.Submittd

job.JobStat==JobStat.Expird

job.JobTitl.IsNullOrWhitSpac()){//....}重构后:

if(CanBDltd(job)){//}privatboolCanBDltd(Jobjob){varinvalidJobStat=job.JobStat==JobStat.Nw

job.JobStat==JobStat.Submittd

job.JobStat==JobStat.Expird;varinvalidJob=string.IsNullOrEmpty(job.JobTitl);rturninvalidJobStat

invalidJob;}

有没有豁然开朗的赶脚?

7.嵌套判断

反例:

varisValid=fals;if(!string.IsNullOrEmpty(usr.UsrNam)){if(!string.IsNullOrEmpty(usr.Password)){if(!string.IsNullOrEmpty(usr.Email)){isValid=tru;}}}rturnisValid;重构后:

if(string.IsNullOrEmpty(usr.UsrNam))rturnfals;if(string.IsNullOrEmpty(usr.Password))rturnfals;if(string.IsNullOrEmpty(usr.Email))rturnfals;rturntru;

第一种代码是受到早期的某些思想:使用一个变量来存储返回结果。事实证明,你一旦知道了结果就应该尽早返回。

8.使用前置条件

反例:

if(!string.IsNullOrEmpty(usrNam)){if(!string.IsNullOrEmpty(password)){//rgistr}ls{thrownwArgumntExcption("usrpasswordcannotbmpty");}}ls{thrownwArgumntExcption("usrnamcannotbmpty");}重构后:

if(string.IsNullOrEmpty(usrNam))thrownwArgumntExcption("usrnamcannotbmpty");if(string.IsNullOrEmpty(password))thrownwArgumntExcption("usrpasswordcannotbmpty");//rgistr

重构后的风格更接近契约编程,首先要满足前置条件,否则免谈。

9.参数过多,超过3个

反例:

publicvoidRgistrUsr(stringusrNam,stringpassword,stringmail,stringphon){}重构后:

publicvoidRgistrUsr(Usrusr){}

过多的参数让读者难以抓住代码的意图,同时过多的参数将会影响方法的稳定性。另外也预示着参数应该聚合为一个Modl

10.方法签名中含有布尔参数

反例:

publicvoidRgistrUsr(Usrusr,boolsndEmail){}重构后:

publicvoidRgistrUsr(Usrusr){}publicvoidSndEmail(Usrusr){}

布尔参数在告诉方法不止做一件事,违反了Doonthing

10.写具有表达力的代码

反例:

privatstringCombinTchnicalBookNamOfAuthor(ListBookbooks,stringauthor){varfiltrBooks=nwListBook();forach(varbookinbooks){if(book.Catgory==BookCatgory.Tchnicalbook.Author==author){filtrBooks.Add(book);}}varnam="";forach(varbookinfiltrBooks){nam+=book.Nam+"

";}rturnnam;}重构后:

privatstringCombinTchnicalBookNamOfAuthor(ListBookbooks,stringauthor){var







































小孩得白癜风能治愈么
白癫疯专科医院



转载请注明地址:http://www.xiyunanhai.com/ldly/1464.html
  • 上一篇文章:
  • 下一篇文章:
  • 热点文章

    • 没有热点文章

    推荐文章

    • 没有推荐文章