日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一堂如何提高代码质量的培训课【转】

發布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一堂如何提高代码质量的培训课【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天這堂培訓課講什么呢?我既不講Spring,也不講Hibernate,更不講Ext,我不講任何一個具體的技術。我們拋開任何具體的技術,來談談如何提高代碼質量。如何提高代碼質量,相信不僅是在座所有人苦惱的事情,也是所有軟件項目苦惱的事情。如何提高代碼質量呢,我認為我們首先要理解什么是高質量的代碼。

高質量代碼的三要素

我們評價高質量代碼有三要素:可讀性、可維護性、可變更性。我們的代碼要一個都不能少地達到了這三要素的要求才能算高質量的代碼。

1.可讀性強

一提到可讀性似乎有一些老生常談的味道,但令人沮喪的是,雖然大家一而再,再而三地強調可讀性,但我們的代碼在可讀性方面依然做得非常糟糕。由于工作的需要,我常常需要去閱讀他人的代碼,維護他人設計的模塊。每當我看到大段大段、密密麻麻的代碼,而且還沒有任何的注釋時常常感慨不已,深深體會到了這項工作的重要。由于分工的需要,我們寫的代碼難免需要別人去閱讀和維護的。而對于許多程序員來說,他們很少去閱讀和維護別人的代碼。正因為如此,他們很少關注代碼的可讀性,也對如何提高代碼的可讀性缺乏切身體會。有時即使為代碼編寫了注釋,也常常是注釋語言晦澀難懂形同天書,令閱讀者反復斟酌依然不明其意。針對以上問題,我給大家以下建議:

1)不要編寫大段的代碼

如果你有閱讀他人代碼的經驗,當你看到別人寫的大段大段的代碼,而且還不怎么帶注釋,你是怎樣的感覺,是不是“嗡”地一聲頭大。各種各樣的功能糾纏在一個方法中,各種變量來回調用,相信任何人多不會認為它是高質量的代碼,但卻頻繁地出現在我們編寫的程序了。如果現在你再回顧自己寫過的代碼,你會發現,稍微編寫一個復雜的功能,幾百行的代碼就出去了。一些比較好的辦法就是分段。將大段的代碼經過整理,分為功能相對獨立的一段又一段,并且在每段的前端編寫一段注釋。這樣的編寫,比前面那些雜亂無章的大段代碼確實進步了不少,但它們在功能獨立性、可復用性、可維護性方面依然不盡人意。從另一個比較專業的評價標準來說,它沒有實現低耦合、高內聚。我給大家的建議是,將這些相對獨立的段落另外封裝成一個又一個的函數。

許多大師在自己的經典書籍中,都鼓勵我們在編寫代碼的過程中應當養成不斷重構的習慣。我們在編寫代碼的過程中常常要編寫一些復雜的功能,起初是寫在一個類的一個函數中。隨著功能的逐漸展開,我們開始對復雜功能進行歸納整理,整理出了一個又一個的獨立功能。這些獨立功能有它與其它功能相互交流的輸入輸出數據。當我們分析到此處時,我們會非常自然地要將這些功能從原函數中分離出來,形成一個又一個獨立的函數,供原函數調用。在編寫這些函數時,我們應當仔細思考一下,為它們取一個釋義名稱,并為它們編寫注釋(后面還將詳細討論這個問題)。另一個需要思考的問題是,這些函數應當放到什么地方。這些函數可能放在原類中,也可能放到其它相應職責的類中,其遵循的原則應當是“職責驅動設計”(后面也將詳細描述)。

下面是我編寫的一個從XML文件中讀取數據,將其生成工廠的一個類。這個類最主要的一段程序就是初始化工廠,該功能歸納起來就是三部分功能:用各種方式嘗試讀取文件、以DOM的方式解析XML數據流、生成工廠。而這些功能被我歸納整理后封裝在一個不同的函數中,并且為其取了釋義名稱和編寫了注釋:

?

?

Java代碼?
  • /**?
  • ?*?初始化工廠。根據路徑讀取XML文件,將XML文件中的數據裝載到工廠中?
  • ?*?@param?path?XML的路徑?
  • ?*/??
  • public?void?initFactory(String?path){??
  • ????if(findOnlyOneFileByClassPath(path)){return;}??
  • ????if(findResourcesByUrl(path)){return;}??
  • ????if(findResourcesByFile(path)){return;}??
  • ????this.paths?=?new?String[]{path};??
  • }??
  • ??
  • /**?
  • ?*?初始化工廠。根據路徑列表依次讀取XML文件,將XML文件中的數據裝載到工廠中?
  • ?*?@param?paths?路徑列表?
  • ?*/??
  • public?void?initFactory(String[]?paths){??
  • ????for(int?i=0;?i<paths.length;?i++){??
  • ????????initFactory(paths[i]);??
  • ????}??
  • ????this.paths?=?paths;??
  • }??
  • ??
  • /**?
  • ?*?重新初始化工廠,初始化所需的參數,為上一次初始化工廠所用的參數。?
  • ?*/??
  • public?void?reloadFactory(){??
  • ????initFactory(this.paths);??
  • }??
  • ??
  • /**?
  • ?*?采用ClassLoader的方式試圖查找一個文件,并調用<code>readXmlStream()</code>進行解析?
  • ?*?@param?path?XML文件的路徑?
  • ?*?@return?是否成功?
  • ?*/??
  • protected?boolean?findOnlyOneFileByClassPath(String?path){??
  • ????boolean?success?=?false;??
  • ????try?{??
  • ????????Resource?resource?=?new?ClassPathResource(path,?this.getClass());??
  • ????????resource.setFilter(this.getFilter());??
  • ????????InputStream?is?=?resource.getInputStream();??
  • ????????if(is==null){return?false;}??
  • ????????readXmlStream(is);??
  • ????????success?=?true;??
  • ????}?catch?(SAXException?e)?{??
  • ????????log.debug("Error?when?findOnlyOneFileByClassPath:"+path,e);??
  • ????}?catch?(IOException?e)?{??
  • ????????log.debug("Error?when?findOnlyOneFileByClassPath:"+path,e);??
  • ????}?catch?(ParserConfigurationException?e)?{??
  • ????????log.debug("Error?when?findOnlyOneFileByClassPath:"+path,e);??
  • ????}??
  • ????return?success;??
  • }??
  • ??
  • /**?
  • ?*?采用URL的方式試圖查找一個目錄中的所有XML文件,并調用<code>readXmlStream()</code>進行解析?
  • ?*?@param?path?XML文件的路徑?
  • ?*?@return?是否成功?
  • ?*/??
  • protected?boolean?findResourcesByUrl(String?path){??
  • ????boolean?success?=?false;??
  • ????try?{??
  • ????????ResourcePath?resourcePath?=?new?PathMatchResource(path,?this.getClass());??
  • ????????resourcePath.setFilter(this.getFilter());??
  • ????????Resource[]?loaders?=?resourcePath.getResources();??
  • ????????for(int?i=0;?i<loaders.length;?i++){??
  • ????????????InputStream?is?=?loaders[i].getInputStream();??
  • ????????????if(is!=null){??
  • ????????????????readXmlStream(is);??
  • ????????????????success?=?true;??
  • ????????????}??
  • ????????}??
  • ????}?catch?(SAXException?e)?{??
  • ????????log.debug("Error?when?findResourcesByUrl:"+path,e);??
  • ????}?catch?(IOException?e)?{??
  • ????????log.debug("Error?when?findResourcesByUrl:"+path,e);??
  • ????}?catch?(ParserConfigurationException?e)?{??
  • ????????log.debug("Error?when?findResourcesByUrl:"+path,e);??
  • ????}??
  • ????return?success;??
  • }??
  • ??
  • /**?
  • ?*?用File的方式試圖查找文件,并調用<code>readXmlStream()</code>解析?
  • ?*?@param?path?XML文件的路徑?
  • ?*?@return?是否成功?
  • ?*/??
  • protected?boolean?findResourcesByFile(String?path){??
  • ????boolean?success?=?false;??
  • ????FileResource?loader?=?new?FileResource(new?File(path));??
  • ????loader.setFilter(this.getFilter());??
  • ????try?{??
  • ????????Resource[]?loaders?=?loader.getResources();??
  • ????????if(loaders==null){return?false;}??
  • ????????for(int?i=0;?i<loaders.length;?i++){??
  • ????????????InputStream?is?=?loaders[i].getInputStream();??
  • ????????????if(is!=null){??
  • ????????????????readXmlStream(is);??
  • ????????????????success?=?true;??
  • ????????????}??
  • ????????}??
  • ????}?catch?(IOException?e)?{??
  • ????????log.debug("Error?when?findResourcesByFile:"+path,e);??
  • ????}?catch?(SAXException?e)?{??
  • ????????log.debug("Error?when?findResourcesByFile:"+path,e);??
  • ????}?catch?(ParserConfigurationException?e)?{??
  • ????????log.debug("Error?when?findResourcesByFile:"+path,e);??
  • ????}??
  • ????return?success;??
  • }??
  • ??
  • /**?
  • ?*?讀取并解析一個XML的文件輸入流,以Element的形式獲取XML的根,?
  • ?*?然后調用<code>buildFactory(Element)</code>構建工廠?
  • ?*?@param?inputStream?文件輸入流?
  • ?*?@throws?SAXException?
  • ?*?@throws?IOException?
  • ?*?@throws?ParserConfigurationException?
  • ?*/??
  • protected?void?readXmlStream(InputStream?inputStream)?throws?SAXException,?IOException,?ParserConfigurationException{??
  • ????if(inputStream==null){??
  • ????????throw?new?ParserConfigurationException("Cann't?parse?source?because?of?InputStream?is?null!");??
  • ????}??
  • ????DocumentBuilderFactory?factory?=?DocumentBuilderFactory.newInstance();??
  • ???????factory.setValidating(this.isValidating());??
  • ???????factory.setNamespaceAware(this.isNamespaceAware());??
  • ???????DocumentBuilder?build?=?factory.newDocumentBuilder();??
  • ???????Document?doc?=?build.parse(new?InputSource(inputStream));??
  • ???????Element?root?=?doc.getDocumentElement();??
  • ???????buildFactory(root);??
  • }??
  • ??
  • /**?
  • ?*?用從一個XML的文件中讀取的數據構建工廠?
  • ?*?@param?root?從一個XML的文件中讀取的數據的根?
  • ?*/??
  • protected?abstract?void?buildFactory(Element?root);??
  • ?

    ?

    完整代碼在附件中。在編寫代碼的過程中,通常有兩種不同的方式。一種是從下往上編寫,也就是按照順序,每分出去一個函數,都要將這個函數編寫完,才回到主程序,繼續往下編寫。而一些更有經驗的程序員會采用另外一種從上往下的編寫方式。當他們在編寫程序的時候,每個被分出去的程序,可以暫時只寫一個空程序而不去具體實現功能。當主程序完成以后,再一個個實現它的所有子程序。采用這樣的編寫方式,可以使復雜程序有更好的規劃,避免只見樹木不見森林的弊病。

    有多少代碼就算大段代碼,每個人有自己的理解。我編寫代碼,每當達到15~20行的時候,我就開始考慮是否需要重構代碼。同理,一個類也不應當有太多的函數,當函數達到一定程度的時候就應該考慮分為多個類了;一個包也不應當有太多的類。。。。。。

    2)釋義名稱與注釋

    我們在命名變量、函數、屬性、類以及包的時候,應當仔細想想,使名稱更加符合相應的功能。我們常常在說,設計一個系統時應當有一個或多個系統分析師對整個系統的包、類以及相關的函數和屬性進行規劃,但在通常的項目中這都非常難于做到。對它們的命名更多的還是程序員來完成。但是,在一個項目開始的時候,應當對項目的命名出臺一個規范。譬如,在我的項目中規定,新增記錄用newadd開頭,更新記錄用editmod開頭,刪除用del開頭,查詢用findquery開頭。使用最亂的就是get,因此我規定,get開頭的函數僅僅用于獲取類屬性。

    注釋是每個項目組都在不斷強調的,可是依然有許多的代碼沒有任何的注釋。為什么呢?因為每個項目在開發過程中往往時間都是非常緊的。在緊張的代碼開發過程中,注釋往往就漸漸地被忽略了。利用開發工具的代碼編寫模板也許可以解決這個問題。

    用我們常用的MyEclipse為例,在菜單“window>>Preferences>>Java>>Code Style>>Code Templates>>Comments”中,可以簡單的修改一下。

    ?



    ?

    ?

    ?

    Files”代表的是我們每新建一個文件(可能是類也可能是接口)時編寫的注釋,我通常設定為:

    Java代碼?
  • /*?
  • ?*?created?on?${date}?
  • ?*/??
  • ??

    Types”代表的是我們新建的接口或類前的注釋,我通常設定為:

    Java代碼?
  • /**?
  • ?*??
  • ?*?@author?${user}?
  • ?*/??
  • ??

    ?

    第一行為一個空行,是用于你寫該類的注釋。如果你采用“職責驅動設計”,這里首先應當描述的是該類的職責。如果需要,你可以寫該類一些重要的方法及其用法、該類的屬性及其中文含義等。

    ${user}代表的是你在windows中登陸的用戶名。如果這個用戶名不是你的名稱,你可以直接寫死為你自己的名稱。

    其它我通常都保持為默認值。通過以上設定,你在創建類或接口的時候,系統將自動為你編寫好注釋,然后你可以在這個基礎上進行修改,大大提高注釋編寫的效率。

    同時,如果你在代碼中新增了一個函數時,通過Alt+Shift+J快捷鍵,可以按照模板快速添加注釋。

    在編寫代碼時如果你編寫的是一個接口或抽象類,我還建議你在@author后面增加@see注釋,將該接口或抽象類的所有實現類列出來,因為閱讀者在閱讀的時候,尋找接口或抽象類的實現類比較困難。

    ?

    ?

    Java代碼?
  • /**?
  • ?*?抽象的單表數組查詢實現類,僅用于單表查詢?
  • ?*?@author?范鋼?
  • ?*?@see?com.htxx.support.query.DefaultArrayQuery?
  • ?*?@see?com.htxx.support.query.DwrQuery?
  • ?*/??
  • public?abstract?class?ArrayQuery?implements?ISingleQuery?{??
  • ...??
  • ??

    2.可維護性

    軟件的可維護性有幾層意思,首先的意思就是能夠適應軟件在部署和使用中的各種情況。從這個角度上來說,它對我們的軟件提出的要求就是不能將代碼寫死。

    1)代碼不能寫死

    我曾經見我的同事將系統要讀取的一個日志文件指定在C盤的一個固定目錄下,如果系統部署時沒有這個目錄以及這個文件就會出錯。如果他將這個決定路徑下的目錄改為相對路徑,或者通過一個屬性文件可以修改,代碼豈不就寫活了。一般來說,我在設計中需要使用日志文件、屬性文件、配置文件,通常都是以下幾個方式:將文件放到與類相同的目錄,使用ClassLoader.getResource()來讀取;將文件放到classpath目錄下,用File的相對路徑來讀取;使用web.xml或另一個屬性文件來制定讀取路徑。

    我也曾見另一家公司的軟件要求,在部署的時候必須在C:/bea目錄下,如果換成其它目錄則不能正常運行。這樣的設定常常為軟件部署時帶來許多的麻煩。如果服務器在該目錄下已經沒有多余空間,或者已經有其它軟件,將是很撓頭的事情。

    2)預測可能發生的變化

    除此之外,在設計的時候,如果將一些關鍵參數放到配置文件中,可以為軟件部署和使用帶來更多的靈活性。要做到這一點,要求我們在軟件設計時,應當更多地有更多的意識,考慮到軟件應用中可能發生的變化。比如,有一次我在設計財務軟件的時候,考慮到一些單據在制作時的前置條件,在不同企業使用的時候,可能要求不一樣,有些企業可能要求嚴格些而有些要求松散些。考慮到這種可能的變化,我將前置條件設計為可配置的,就可能方便部署人員在實際部署中進行靈活變化。然而這樣的配置,必要的注釋說明是非常必要的。

    軟件的可維護性的另一層意思就是軟件的設計便于日后的變更。這一層意思與軟件的可變更性是重合的。所有的軟件設計理論的發展,都是從軟件的可變更性這一要求逐漸展開的,它成為了軟件設計理論的核心。

    總結

    以上是生活随笔為你收集整理的一堂如何提高代码质量的培训课【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久久久久久久成人 | 亚洲国产精品视频一区二区 | 午夜视频久久久 | 91在线观看. | 在线免费看黄视频 | 欧美在线视频免费 | 亚洲老老头同性老头交j | 男女无遮挡做爰猛烈视频 | 国产一级爱 | 善良的少妇伦理bd中字 | 好吊色欧美一区二区三区视频 | 黑帮大佬和我的三百六十五天 | 黄色大片在线 | 久久影院视频 | 国产乱码精品一品二品 | 国产精品福利一区 | 亚洲AV无码一区二区三区蜜桃 | 天天射日日操 | 九九在线观看高清免费 | 狠狠躁18三区二区一区视频 | 禁网站在线观看免费视频 | 国产亚洲视频一区 | 片集网| 中文字幕一区二区在线播放 | 国产免费黄色网址 | 亚洲搞av | 91国偷自产一区二区三区老熟女 | 欧类av怡春院 | 一区二区成人精品 | 麻豆国产一区二区三区四区 | 亚洲午夜精品久久久久久app | 亚洲熟女乱色一区二区三区久久久 | 国产精彩视频在线 | 国产成人aaa | 性折磨bdsm欧美激情另类 | 一区二区在线视频观看 | 欧美1页| 中文字幕免费 | 亚洲av综合av一区二区三区 | 无码精品人妻一区二区三区影院 | 日韩精品视频中文字幕 | 欧美日韩视频在线播放 | 亚洲国产网 | 亚洲av永久无码精品三区在线 | 欧美成人一区二区三区片免费 | 黄在线免费看 | 精品999久久久一级毛片 | 九九热视频这里只有精品 | 狠狠ri| 亚洲色图图片区 | 伊人宗合 | 国产理论 | 日本一本视频 | 四虎精品一区二区 | 蜜臀av午夜精品 | 日本女优在线看 | 激情综合五月网 | 蜜臀av一区二区三区激情综合 | 日韩综合区 | 亚洲h网站 | 久久综合免费视频 | 日本黄色免费视频 | 中文字幕色站 | 精品乱码一区二区三四区视频 | 欧美毛片视频 | 肉嫁高柳在线 | 91人人看| 影视av | 黄色片在线免费观看视频 | 在线观看国产免费av | 国产社区在线 | 狠狠爱成人 | 91视频免费网址 | 色偷偷资源网 | 亚洲一区视频在线 | 日韩三级在线 | 国产深夜福利在线 | 麻豆精品免费视频 | 亚洲 欧美 国产 另类 | 日韩精品人妻一区二区三区免费 | 操女人的逼逼 | 欧美人妻少妇一区二区三区 | 中文字幕av在线免费观看 | 天天色天天干天天色 | 一级特黄aaa | 国产a级片视频 | 国产一区二区三区在线观看视频 | 国产精品入口免费 | 成人wwwww免费观看 | 69天堂| 成人毛片在线视频 | 巨胸喷奶水www久久久免费动漫 | 性生交大全免费看 | 国产91在线播放精品91 | 九九热综合 | 搞中出| 色中文字幕 | www.中文字幕av | 蜜桃av成人永久免费 |