連基礎(chǔ)都沒有打牢,你還想多高的成就--代碼注釋

三毛說過:基礎(chǔ)是重要的東西,沒有基礎(chǔ)的人,將來走任何一條路都比基礎(chǔ)深厚的人來得辛苦和單薄

當(dāng)我們的開發(fā)Leader或者項目組需要我們編寫符合各種規(guī)則的代碼,我一直是一個不守規(guī)矩的“壞小孩”。我們一直強調(diào)我們的開發(fā)人員寫短的方法,必須編寫注釋,我們甚至用各種工具去Check我們的小伙伴的代碼,注釋,命名規(guī)范,方法長度我們用盡了Check Style里面的定義。但是往往我們忘了了初衷,我們?yōu)槭裁匆⑨?,我們?yōu)槭裁匆?guī)范,我們?yōu)槭裁匆椒ā岸绦《伞薄J堑?,為什么?為什么?為什么?/p>

別給糟糕的代碼加上注釋----重新寫吧!

不記得什么時候開始,我們有了這樣的一個想法,糟糕的代碼可以用完美的注釋來彌補,真的真的是這樣嗎?糟糕的代碼,就是糟糕的代碼,不管用多么好的注釋去彌補還是糟糕的,就像一個腐壞的食品,你在用什么華麗的包裝去包裝它,他還是壞的,必須扔掉,重新做。

什么也比不上放置良好的注釋來的有用,什么也比不上亂七八糟的注釋更加有能耐搞亂一個模塊,什么也不會比陳舊,提供錯誤信息的注釋要有更加的破壞性。

記得在做一個項目的時候,有一位高手就告訴我,假如你得編程語言有足夠的表達力,或者我們擅長用這些語言來表達意圖,就不那么需要注釋,因為你的注釋會將別人帶入到溝里面。

是的帶入到溝里面,當(dāng)我的代碼編寫的越來越多,或者說,閱讀的代碼變多的時候,真的。我已經(jīng)不知道多少次被人帶入到溝里面了。

代碼是一直會變的也在一直演變中,從這里遷移到那里,彼此分離,然后又和別的代碼重新組合,變成一對,但是注釋我們不會總是跟著代碼在變動。

糟糕的代碼,注釋也沒法彌補

用代碼來闡述你的意圖

//檢查員工是否有資格獲得免費的福利

if((employee.flags && HOURLY_FLAG)&&(employee.age>65))

if(employee.isEligibleForFullBenefits())

你會選擇哪一個,讓別人第一時間了解的意圖,即使在不知道你的方法具體實現(xiàn)的時候,讓閱讀的人理解你的意圖。

有時候,代碼本身不足以解釋其行為,不幸的消息是,許多開發(fā)人員常常認(rèn)為代碼很少,如果可以的話,能用注釋做好解釋工作。

好的注釋,有一些注釋必須要有的,也是有利的。不過要記住,唯一真正好的注釋是你想辦法不寫注釋。(但是我不完全認(rèn)可這個)。

法律信息

在我們使用很多開源項目的時候,我們往往會看到以下注釋

//Copyright (C) 2003,2004,2005 by Object Mentor,Inc,All rights reserved.

//Released under the terms of the GNU General Public License version 2 or laster.

提供信息注釋

有時候,用注釋來提供有用的信息也是恰其好處。比如

/**

* @return Responder Returns an instance of the Responder being tested.

**/

protected abstract Responder responderInstance();

//format matched kk:mm:ss EEE,MMM dd,yyyy

Pattern timMatcher = Pattern.compile("\\d*:\\d*:\\d* \\w* \\d* \\d*");

這個注釋說明了,該正則表達式的作用在匹配一個經(jīng)過SimleDateFormat方法格式化完的一個字符串的時間和日期。

對意圖的解釋

有時候,注釋不僅提供了有關(guān)實現(xiàn)的具體說明,而且還提供了某個決定后面的意圖。

例如我們在讀取文件的時候,我們提供出來很多方法的時候,往往我們沒有寫在讀寫完文件的時候,告訴調(diào)用的人員,你需要關(guān)閉文件流,有人這時候會說,這些事程序猿肯定知道的??隙ㄖ赖模淮硪欢ㄖ?,或者一定遵守的。

比如

a.compareTo(b) == 0?

a.compareTo(b)<0

a.compareTo(b)>0

這些其實我們不需要寫注釋的,但是往往我們還是會寫,為什么,因為我們要強調(diào)。

a.compareTo(b) == 0 //a ==b

a.compareTo(b)<0 //a<b

a.compareTo(b)>0 //a>b

這時候,你會發(fā)現(xiàn)有時候好的注釋,往往會讓你“蛋疼”。

TODO注釋

TODO,我想很多人已經(jīng)用過了,TODO是一種程序猿認(rèn)為應(yīng)該做的,比如在某種情況下,目前我們可能還不需要完成某種工作,我們就必須使用TODO

公共API中的JavaDoc

如果你在做一些共通的東西的話,好的JavaDoc將會為你省下很多解釋的時間。因為我們可以使用Javadoc生成很好的API文檔提供給別人。這樣的話,使用人員就可以很明確的明白你的意圖,或者方法的作用

請不要喃喃自語

public void loadProperties(){

? ?try{

? ? ? ? ? ? String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;

? ? ? ? ? ? FileInputStream propertiesStream = new FileInputStream(propertiesPath);

? ? ? ? ? ?loadedProperties.load(propertiesStream);

? ? ? ? }catch(IOException ex){

? ? ? ? ?//No Properties files means all defaults are loaded

? ? ? ? ?}

}


誰能解釋一下Catch里面注釋的意義,這個可能是開發(fā)人員對于沒有Properties文件的情況做的一個特殊處理,但是有沒有闡述情況,因為在Catch里面只是空空的注釋,別沒有對這塊做任何的操作,難道開發(fā)人員會在后面發(fā)現(xiàn)有問題的情況的時候補充代碼嗎?那么為什么我們不是用TODO呢?

循規(guī)蹈矩的注釋

還記得我們循規(guī)蹈矩的注釋嗎?那些循規(guī)蹈矩的注釋是否真的很有用呢?是不是只是為了保證我們的Check Style通過?好吧,是的。就是為了Check Style通過。但是那些注釋的作用又有多少呢?我可以為是0.

/**

*

*@param title The title of the CD

*@param author The author of the CD

*@param track The number of tracks on the CD

*@param durationInMinutes The duration of the CD in minutes

*/

public void addCd(String title,String author,int tracks,int durationInMinutes){

.......

}

我們是否可以不需要這些我們?yōu)榱薈heck Style通過,而編寫這些廢話的注釋呢?

廢話注釋

廢話注釋,就是那些寫的是廢話的注釋,沒有任何營養(yǎng)的注釋,說的再難聽一點,就是,你寫的那些事廢話,沒有任何價值,你在寫那些的時候,就是浪費人月,浪費時間。

/**

* Default constructor.

**/

public AnnualDateRule(){

}


你告訴我,誰不知道這是默認(rèn)構(gòu)造函數(shù),

還有更加規(guī)范的廢話

/**

* Returns the day of the month.

*@return the day of the month .

public int getDayOfMonth(){

return this.dayOfMonth.

}


這樣的規(guī)范注釋,我們見得很多,有時候我們會糾結(jié),要不要加這些廢話的注釋,但是當(dāng)我們命名規(guī)范或者有含義的時候,我真的認(rèn)為不需要了。除非,你想表達的更加清晰明朗。

還有更加廢話的注釋。

/**The name*/

private String name;

/**The Version*/

private String version;

妹的,想罵臟字了,難道我不知道這個是name,那個是version,要你說。

當(dāng)我們思維達到一個邊界的時候,我們往往會忘了初衷,難道不是嗎?我們的規(guī)范,我們的要求,往往忘了為什么。

寫了這么多,參考一下別人的注釋吧!


/**

* Spring Boot 啟動類,加載需要的Bean和設(shè)置啟動時候Config掃描類.

*@author jiang_nan

*/

@Configuration

@Import({

DispatcherServletAutoConfiguration.class,

EmbeddedServletContainerAutoConfiguration.class,

ErrorMvcAutoConfiguration.class,

FreeMarkerAutoConfiguration.class,

HttpEncodingAutoConfiguration.class,

HttpMessageConvertersAutoConfiguration.class,

JacksonAutoConfiguration.class,

MultipartAutoConfiguration.class,

PersistenceExceptionTranslationAutoConfiguration.class,

PropertyPlaceholderAutoConfiguration.class,

RedisAutoConfiguration.class,

ServerPropertiesAutoConfiguration.class,

WebMvcAutoConfiguration.class,

WebSocketAutoConfiguration.class

})

@EnableTransactionManagement// 開啟注解事務(wù)管理,等同于xml配置文件中的

@ComponentScan(basePackages={"com.msk.batch"})

public classApplicationimplementsTransactionManagementConfigurer {

@Resource

privateEnvironmentenvironment;

@Resource

privatePlatformTransactionManagerdataSourceTransactionManager;

@Bean

publicDataSourcedataSource(){

DruidDataSource dataSource =newDruidDataSource();

String url =environment.getProperty("spring.datasource.url");

dataSource.setUrl(url);

String userName =environment.getProperty("spring.datasource.username");

dataSource.setUsername(userName);

String password =environment.getProperty("spring.datasource.password");

dataSource.setPassword(password);

dataSource.setInitialSize(2);

dataSource.setMaxActive(20);

dataSource.setMinIdle(0);

dataSource.setMaxWait(60000);

dataSource.setValidationQuery("SELECT 1");

dataSource.setTestOnBorrow(false);

dataSource.setTestWhileIdle(true);

dataSource.setPoolPreparedStatements(false);

returndataSource;

}

@Bean

publicJdbcTemplatejdbcTemplate(){

return newJdbcTemplate(dataSource());

}

@Bean

publicPlatformTransactionManagertxManager(DataSource dataSource) {

return newDataSourceTransactionManager(dataSource);

}

@Override

publicPlatformTransactionManagerannotationDrivenTransactionManager() {

returndataSourceTransactionManager;

}

public static voidmain(String[] args)throwsException {

SpringApplication.run(Application.class,args);

}

}

沒有一行多余的注釋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,697評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,853評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,036評論 0 11
  • 7.27號(周一),進入公司第一天實習(xí),做五休二 一、每天總結(jié) 7.27 熟悉了一下環(huán)境 7.28 練習(xí)git,學(xué)...
    箱貓日和閱讀 344評論 1 3
  • 小時候老師總是講祖國是母親,我們是花朵,但是實際上我們也不是什么花朵,我們就是鄭智化歌里的那根“小小的草,風(fēng)吹雨打...
    摩訶婆羅多閱讀 1,120評論 0 2

友情鏈接更多精彩內(nèi)容