導航:首頁 > 程序命令 > 程序員關注代碼和質量

程序員關注代碼和質量

發布時間:2023-08-18 23:33:10

Ⅰ 如何編寫高質量的代碼

1. 打好基礎
寫出高質量代碼,並不是搭建空中樓閣,需要有一定的基礎,這里我重點強調與代碼質量密切相關的幾點:
掌握好開發語言,比如做Android就必須對Java足夠熟悉,《Effective Java》一書就是教授大家如何更好得掌握Java, 寫出高質量Java代碼。
熟悉開發平台, 不同的開發平台,有不同的API, 有不同的工作原理,同樣是Java代碼,在PC上寫與Android上寫很多地方不一樣,要去熟悉Android編程的一些特性,iOS編程的一些特性,了解清楚這些,才能寫出更加地道的代碼,充分發揮各自平台的優勢。
基礎的數據結構與演算法,掌握好這些在解決一些特定問題時,可以以更加優雅有效的方式處理。
基礎的設計原則,無需完全掌握23種經典設計模式,只需要了解一些常用的設計原則即可,甚至你也可以只了解什麼是低耦合,並在你的代碼中堅持實踐,也能寫出很不錯的代碼。
2. 代碼標准
代碼標准在團隊合作中尤為重要,誰也不希望一個項目中代碼風格各異,看得讓人糟心,即便是個人開發者,現在也需要跟各種開源項目打交道。標准怎麼定是一個老生常談的話題,我個人職業生涯中經歷過很多次的代碼標准討論會議,C++, C#, Java等等,大家有時會堅持自己的習慣不肯退讓。可現如今時代不一樣了,Google等大廠已經為我們制定好了各種標准,不用爭了,就用這些業界標准吧。
3. 想好再寫
除非你很清楚你要怎麼做,否則我不建議邊做邊想。
你真的搞清楚你要解決的問題是什麼了嗎?你的方案是否能有效?有沒有更優雅簡單的方案?准備怎麼設計它,必要的情況下,需要有設計文檔,復雜一些的設計需要有同行評審,寫代碼其實是很簡單的事情,前提是你得先想清楚。
4. 代碼重構
重構對於代碼質量的重要性不言而喻,反正我是很難一次把代碼寫得讓自己滿意、無可挑剔,《重構》這本書作為業內經典也理應人人必讀,也有其他類似的教授重構技巧的書,有些也非常不錯,遺憾的是我發現很多工作多年的同學甚至都沒有了解過重構的概念。
5. 技術債務
知乎上最近有個熱門問題《為什麼有些大公司技術弱爆了?》,其實裡面提到的很多歸根結底都是技術債務問題,這在一些大公司尤為常見。技術債務話題太大,但就代碼質量而言,我只想提一下不要因為這些債是前人留下的你就不去管,現實是沒有多少機會讓你從一個清爽清新的項目開始做起,你不得不去面對這些,你也沒法完全不跟這些所謂的爛代碼打交道。
因此我建議各位:當你負責一個小模塊時,除了把它做好之外,也要順便將與之糾纏在一起的技術債務還掉,因為這些債務最終將是整個團隊來共同承擔,任何一個人都別想獨善其身,如果你還對高質量代碼有追求的話。
作為團隊的技術負責人,也要頂住壓力,鼓勵大家勇於做出嘗試,引導大家不斷改進代碼質量,不要總是畏手畏腳,停滯不前,真要背鍋也得上,要有擔當。
6. 代碼審查
我曾經聽過一些較高級別的技術分享,竟然還不時聽到一些呼籲大家要做代碼審查的主題,我以為在這個級別的技術會議上,不應再討論代碼審查有什麼好,為什麼要做代碼審查之類的問題。同時我接觸過相當多所謂國內一線互聯網公司,竟有許多是不做代碼審查的,這一度讓我頗為意外。
這里也不想多談如何做好代碼審查,只是就代碼質量這點,不客氣地說:沒有過代碼審查經歷的同學,往往很難寫出高質量的代碼,尤其是在各種追求速度的糙快猛創業公司。
7. 靜態檢查
很多代碼上的問題,都可以通過一些工具來找到,某些場景下,它比人要靠譜得多,至少不會出現某些細節上的遺漏,同時也能有效幫助大家減少代碼審查的工作量。
Android開發中有Lint, Find bugs, PMD等優秀靜態檢查工具可用,通過改進這些工具找出的問題,就能對語法的細節,規范,編程的技巧有更多直觀了解。
建議最好與持續集成(CI),代碼審查環境配套使用, 每次提交的代碼都能自動驗證是否通過了工具的代碼檢查,通過才允許提交。
8. 單元測試
Android單元測試,一直備受爭議,主要還是原生的測試框架不夠方便,每跑一次用例需要在模擬器或者真機上運行,效率太低,也不方便在CI環境下自動構建單元測試,好在有Robolectric,能幫我們解決部分問題。
單元測試的一個非常顯著的優點是,當你需要修改大量代碼時,盡管放心修改,只需要保證單元測試用例通過即可,無需瞻前顧後。
9. 充分自測
有一種說法:程序員最害怕的是他自己寫的代碼,尤其是准備在眾人面前show自己的工作成果時,因此在寫完代碼後,需要至少跑一遍基本的場景,一些簡單的異常流。在把你的工作成果提交給測試或用戶前,充分自測是基本的職業素養,不要總想著讓測試幫你找問題,隨便用幾下就Crash的東西,你好意思拿給別人嗎?
10. 善用開源
並非開源的東西,質量就高,但至少關注度較高,使用人數較多,口碑較好的開源項目,質量是有一定保證的,這其中的道理很簡單。即便存在一些問題,也可以通過提交反饋,不斷改進。最重要的是,你自己花時間造的輪子,需要很多精力維護,而充分利用開源項目,能幫助你節省很多時間,把精力專注在最需要你關心的問題上。

Ⅱ 對於程序員,提高軟體開發的質量和效率該從那些方面努力

1.提高代碼的規范性。編碼規范 可以提高代碼的可讀性,並且在代碼修改的時候很容易。
2.對功能進行分類,並拆分。分析出幾種處理邏輯。編寫代碼時,部分代碼可以。可以提編碼速度。
3.對功能進行分類,並合並。提出共通類。
4.不同的package對應不同的功能。

簡單的說,每天寫幾百行代碼。堅持半年或者1年,就知道什麼方式是適合你的了。 不寫代碼,光想,十年也還是那個水平。每個人的邏輯思維是不一樣的,寫代碼的方式也是不一樣的。有時間問,還不如多寫寫。或者,自己模擬現實個場景(或公司管理制度之類的),然後實現。寫幾個,很自然的就知道自己該怎麼寫了。

Ⅲ 軟體工程 程序員保證代碼質量的手段的先後順序是怎樣的

保證代碼質量的順序如下:

1)代碼風格
在項目開發之初,往往會制定一個代碼編寫的規范,實際上,這個代碼規范就包含了整個項目組的代碼風格。由於軟體開發人員的設計習慣不同,如果不統一代碼風格,一個項目中的代碼將五花八門,如變數和常量的命名、介面與實現類的注釋、何時回車、怎樣縮進等等。一個五花八門的設計風格,必將為日後的維護與改進帶來困難。
通過代碼復查,一方面督促開發人員按照規范編寫代碼,另一方面也使開發人員自身形成良好的編程習慣。代碼風格的審查,由於內容比較單一,常常可以通過一些代碼復查的工具來自動完成,提高復查的效率。
2)重大缺陷
在一些關於代碼復查的文章中,列出了一個常常的單子,描述了代碼復查應當著重注意的重大缺陷,它們包括:存在SQL注入、易受跨站點腳本攻擊、緩存區溢出、託管代碼等等。項目組可以不斷積累重大缺陷的審查項目,並在每次審查中逐一檢查。重大缺陷審查是一個繁瑣而細致的工作,如果能編寫或使用一些審查軟體,可以大大提高審查效率。
3)設計邏輯與思路的審查
審查是代碼復查中最核心、最有價值的部分。代碼風格與重大缺陷的審查,雖然重要但簡單而機械,可以通過軟體自動檢查;而設計邏輯與思路的審查,卻是復雜而有深度的審查,需要有一定理論深度和編碼經驗的人才能完成,而且對新手尤其重要。前面提到,新手是任何項目組不可避免的問題。
通過代碼復查,讓老手去指導新手,讓團隊整體素質得到提高。具體辦法就是,在新手完成編碼以後,讓老手去進行代碼復查,指出新手的問題,指導新手設計。這樣的過程最初可能需要重構,甚至重新編碼。但經過這樣的過程,新手將逐漸熟練,迅速成為老手,使整體團隊素質提高。

Ⅳ 程序員代碼質量的好壞是如何區別的

現在的程序設計是一個系統的過程,程序員代碼質量的高低往往也與他所處的團隊有較大的關系,也就是說頂層的設計與代碼質量有直接的關系。所以說優秀的團隊往往都是優秀的代碼,但是普通的團隊往往很難寫出優秀的代碼。
代碼的編寫大致上經歷幾個步驟,第一個步驟是頂層設計(架構師)。
頂層設計包括軟體架構設計、技術方案等內容,落實到代碼上往往就是大量介面的定義。好的設計需要考慮三方面因素,分別是結構性(模塊化)、完整性、擴展性,當然還需要考慮可移植性,通常結構性好的代碼移植性也會比較不錯。
第二步是核心代碼的實現(研發級程序員)。
有的團隊也把這部分稱作為「容器」開發,簡單的說就是功能性平台開發,目的是實現平台級API。這部分代碼的開發是整個軟體開發的核心部分,承擔這部分開發任務的程序員往往就是我們所說的研發級程序員。研發級程序員代碼質量的衡量標准主要在演算法設計與實現上,性能指標是考核的重要因素,另外還要考慮穩定性和完整性等核心因素。
第三步是功能編寫(應用級程序員)。
功能編寫簡單的說就是完成具體的業務邏輯實現,需要調用平台提供的API完成具體的功能。這部分程序員占據了程序員群體的大部分比例,也就是通常所說的應用級程序員。應用級程序員的代碼質量主要從代碼編寫結構上來看,比如是否有標準的打包、命名、注釋,以及代碼整體結構是否清晰,邏輯結構是否清晰等方面。
往往程序員代碼的質量會隨著編程經驗的提高而不斷得到提高。
我做軟體開發多年,目前的主要研究方向是大數據和人工智慧,也在帶大數據方向的研究生,我會陸續在頭條上寫一些關於大數據方面的文章,感興趣的朋友可以關注我的頭條號,相信一定會有所收獲。
如果有大數據方面的問題,也可以咨詢我,
謝謝!

Ⅳ 有哪些質量上乘的程序員必關注的網站或論壇

CSDN是很早的了,到現在還是經久不衰,是一個非常大的論壇,還有github,有很多優秀的代碼,世界上的碼農都在貢獻著,其他的還有一些比如segmentfault這種近些年來流行起來的網站。

Ⅵ 如何提高代碼質量6

高質量代碼的三要素 我們評價高質量代碼有三要素:可讀性、可維護性、可變更性。我們的代碼要一個都不能少地達到了這三要素的要求才能算高質量的代碼。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); /** * 初始化工廠。根據路徑讀取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)釋義名稱與注釋 我們在命名變數、函數、屬性、類以及包的時候,應當仔細想想,使名稱更加符合相應的功能。我們常常在說,設計一個系統時應當有一個或多個系統分析師對整個系統的包、類以及相關的函數和屬性進行規劃,但在通常的項目中這都非常難於做到。對它們的命名更多的還是程序員來完成。但是,在一個項目開始的時候,應當對項目的命名出台一個規范。譬如,在我的項目中規定,新增記錄用new或add開頭,更新記錄用edit或mod開頭,刪除用del開頭,查詢用find或query開頭。使用最亂的就是get,因此我規定,get開頭的函數僅僅用於獲取類屬性。注釋是每個項目組都在不斷強調的,可是依然有許多的代碼沒有任何的注釋。為什麼呢?因為每個項目在開發過程中往往時間都是非常緊的。在緊張的代碼開發過程中,注釋往往就漸漸地被忽略了。利用開發工具的代碼編寫模板也許可以解決這個問題。用我們常用的MyEclipse為例,在菜單「window>>Preferences>>Java>>Code Style>>Code Templates>>Comments」中,可以簡單的修改一下。「Files」代表的是我們每新建一個文件(可能是類也可能是介面)時編寫的注釋,我通常設定為:Java代碼 /* * created on ${date} */ /* * created on ${date} */「Types」代表的是我們新建的介面或類前的注釋,我通常設定為:Java代碼 /** * * @author ${user} */ /** * * @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 { ... /** * 抽象的單表數組查詢實現類,僅用於單表查詢 * @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)預測可能發生的變化 除此之外,在設計的時候,如果將一些關鍵參數放到配置文件中,可以為軟體部署和使用帶來更多的靈活性。要做到這一點,要求我們在軟體設計時,應當更多地有更多的意識,考慮到軟體應用中可能發生的變化。比如,有一次我在設計財務軟體的時候,考慮到一些單據在製作時的前置條件,在不同企業使用的時候,可能要求不一樣,有些企業可能要求嚴格些而有些要求鬆散些。考慮到這種可能的變化,我將前置條件設計為可配置的,就可能方便部署人員在實際部署中進行靈活變化。然而這樣的配置,必要的注釋說明是非常必要的。軟體的可維護性的另一層意思就是軟體的設計便於日後的變更。這一層意思與軟體的可變更性是重合的。所有的軟體設計理論的發展,都是從軟體的可變更性這一要求逐漸展開的,它成為了軟體設計理論的核心。3.可變更性 前面我提到了,軟體的變更性是所有軟體理論的核心,那麼什麼是軟體的可變更性呢?按照現在的軟體理論,客戶對軟體的需求時時刻刻在發生著變化。當軟體設計好以後,為應對客戶需求的變更而進行的代碼修改,其所需要付出的代價,就是軟體設計的可變更性。由於軟體合理地設計,修改所付出的代價越小,則軟體的可變更性越好,即代碼設計的質量越高。一種非常理想的狀態是,無論客戶需求怎樣變化,軟體只需進行適當地修改就能夠適應。但這之所以稱之為理想狀態,因為客戶需求變化是有大有小的。如果客戶需求變化非常大,即使再好的設計也無法應付,甚至重新開發。然而,客戶需求的適當變化,一個合理地設計可以使得變更代價最小化,延續我們設計的軟體的生命力。1)通過提高代碼復用提高可維護性 我曾經遇到過這樣一件事,我要維護的一個系統因為應用范圍的擴大,它對機關級次的計算方式需要改變一種策略。如果這個項目統一採用一段公用方法來計算機關級次,這樣一個修改實在太簡單了,就是修改這個公用方法即可。但是,事實卻不一樣,對機關級次計算的代碼遍布整個項目,甚至有些還寫入到了那些復雜的SQL語句中。在這樣一種情況下,這樣一個需求的修改無異於需要遍歷這個項目代碼。這樣一個實例顯示了一個項目代碼復用的重要,然而不幸的是,代碼無法很好復用的情況遍布我們所有的項目。代碼復用的道理十分簡單,但要具體運作起來非常復雜,它除了需要很好的代碼規劃,還需要持續地代碼重構。對整個系統的整體分析與合理規劃可以根本地保證代碼復用。系統分析師通過用例模型、領域模型、分析模型的一步一步分析,最後通過正向工程,生成系統需要設計的各種類及其各自的屬性和方法。採用這種方法,功能被合理地劃分到這個類中,可以很好地保證代碼復用。採用以上方法雖然好,但技術難度較高,需要有高深的系統分析師,並不是所有項目都能普遍採用的,特別是時間比較緊張的項目。通過開發人員在設計過程中的重構,也許更加實用。當某個開發人員在開發一段代碼時,發現該功能與前面已經開發功能相同,或者部分相同。這時,這個開發人員可以對前面已經開發的功能進行重構,將可以通用的代碼提取出來,進行相應地改造,使其具有一定的通用性,便於各個地方可以使用。一些比較成功的項目組會指定一個專門管理通用代碼的人,負責收集和整理項目組中各個成員編寫的,可以通用的代碼。這個負責人同時也應當具有一定的代碼編寫功力,因為將專用代碼提升為通用代碼,或者以前使用該通用代碼的某個功能,由於業務變更,而對這個通用代碼的變更要求,都對這個負責人提出了很高的能力要求。雖然後一種方式非常實用,但是它有些亡羊補牢的味道,不能從整體上對項目代碼進行有效規劃。正因為兩種方法各有利弊,因此在項目中應當配合使用。2)利用設計模式提高可變更性 對於初學者,軟體設計理論常常感覺晦澀難懂。一個快速提高軟體質量的捷徑就是利用設計模式。這里說的設計模式,不僅僅指經典的32個模式,是一切前人總結的,我們可以利用的、更加廣泛的設計模式。a. if...else...這個我也不知道叫什麼名字,最早是哪位大師總結的,它出現在Larman的《UML與模式應用》,也出現在出現在Mardin的《敏捷軟體開發》。它是這樣描述的:當你發現你必須要設計這樣的代碼:「if...elseif...elseif...else...」時,你應當想到你的代碼應當重構一下了。我們先看看這樣的代碼有怎樣的特點。Java代碼 if(var.equals("A")){ doA(); }else if(var.equals("B")){ doB(); }else if(var.equals("C")){ doC(); }else{ doD(); } if(var.equals("A")){ doA(); }else if(var.equals("B")){ doB(); }else if(var.equals("C")){ doC(); }else{ doD(); }這樣的代碼很常見,也非常平常,我們大家都寫過。但正是這樣平常才隱藏著我們永遠沒有注意的問題。問題就在於,如果某一天這個選項不再僅僅是A、B、C,而是增加了新的選項,會怎樣呢?你也許會說,那沒有關系,我把代碼改改就行。然而事實上並非如此,在大型軟體研發與維護中有一個原則,每次的變更盡量不要去修改原有的代碼。如果我們重構一下,能保證不修改原有代碼,僅僅增加新的代碼就能應付選項的增加,這就增加了這段代碼的可維護性和可變更性,提高了代碼質量。那麼,我們應當如何去做呢?經過深入分析你會發現,這里存在一個對應關系,即A對應doA(),B對應doB()...如果將doA()、doB()、doC()...與原有代碼解耦,問題就解決了。如何解耦呢?設計一個介面X以及它的實現A、B、C...每個類都包含一個方法doX(),並且將doA()的代碼放到A.doX()中,將doB()的代碼放到B.doX()中...經過以上的重構,代碼還是這些代碼,效果卻完全不一樣了。我們只需要這樣寫:Java代碼 X x = factory.getBean(var); x.doX(); X x = factory.getBean(var);x.doX();這樣就可以實現以上的功能了。我們看到這里有一個工廠,放著所有的A、B、C...並且與它們的key對應起來,並且寫在配置文件中。如果出現新的選項時,通過修改配置文件就可以無限制的增加下去。這個模式雖然有效提高了代碼質量,但是不能濫用,並非只要出現if...else...就需要使用。由於它使用了工廠,一定程度上增加了代碼復雜度,因此僅僅在選項較多,並且增加選項的可能性很大的情況下才可以使用。另外,要使用這個模式,繼承我在附件中提供的抽象類XmlBuildFactoryFacade就可以快速建立一個工廠。如果你的項目放在spring或其它可配置框架中,也可以快速建立工廠。設計一個Map靜態屬性並使其V為這些A、B、C...這個工廠就建立起來了。b.策略模式 也許你看過策略模式(strategy model)的相關資料但沒有留下太多的印象。一個簡單的例子可以讓你快速理解它。如果一個員工系統中,員工被分為臨時工和正式工並且在不同的地方相應的行為不一樣。在設計它們的時候,你肯定設計一個抽象的員工類,並且設計兩個繼承類:臨時工和正式工。這樣,通過下塑類型,可以在不同的地方表現出臨時工和正式工的各自行為。在另一個系統中,員工被分為了銷售人員、技術人員、管理人員並且也在不同的地方相應的行為不一樣。同樣,我們在設計時也是設計一個抽象的員工類,並且設計數個繼承類:銷售人員、技術人員、管理人員。現在,我們要把這兩個系統合並起來,也就是說,在新的系統中,員工既被分為臨時工和正式工,又被分為了銷售人員、技術人員、管理人員,這時候如何設計。如果我們還是使用以往的設計,我們將不得不設計很多繼承類:銷售臨時工、銷售正式工、技術臨時工、技術正式工...如此的設計,在隨著劃分的類型,以及每種類型的選項的增多,呈笛卡爾增長。通過以上一個系

Ⅶ [探討]提高代碼質量的方法有哪些

1. 代碼風格和規范:

多看看網上的一些代碼規范,仔細思考一下制定這些規范的出發點是什麼。例如Oracle(前

SUN)公司的代碼規范,Google的代碼規范 。

2. 學習最佳實踐

在編碼中遇到的各種大大小小的問題,首先不是自己去「閉門造車」的冥思苦想,多用

Google,搜搜是否已經有現成的解決方案。

3. 閱讀優秀的開源代碼

網上有很多優秀的開源項目,針對你自己項目中遇到的問題,找找類似的開源項目,學習、

研究,最重要的是變成自己的東西。

4. 學好英語

英語是目前所有編程語言的基礎。你的文件名、類名、方法名、變數名都是需要一個好的英

語基礎才能夠起得合適。任何的業務邏輯,都需要你使用以英語為基礎的計算機語言表達出來。

英語不好,你的代碼永遠看起來不專業。

書籍涵蓋的主題從個人責任、職業發展,知道用於使代碼保持靈活、並且易於改編和復用的

各種架構技術。

總結起來方法有三:平時多練手,多閱讀優秀的源碼,閱讀優秀的編程技巧類型的書。

閱讀全文

與程序員關注代碼和質量相關的資料

熱點內容
私有雲主要伺服器 瀏覽:939
為什麼主題解壓那麼慢 瀏覽:860
怎麼下載掃描二維碼的手機app 瀏覽:727
雲伺服器創建私有鏡像的時候一定要關機嗎 瀏覽:115
php開發學習門戶 瀏覽:385
傳奇游戲伺服器怎麼設置 瀏覽:823
敲擊東西解壓完整版 瀏覽:401
刺絡學pdf 瀏覽:868
怎麼給手機文件夾設置封面 瀏覽:931
汽車保養app怎麼用 瀏覽:62
線程javalock 瀏覽:896
c語言編譯運行結果查看器 瀏覽:112
androidpx轉dip 瀏覽:841
西藏編譯局是什麼級別 瀏覽:1001
php提交代碼 瀏覽:597
如何用命令查找並刪除代碼塊 瀏覽:582
python初學路線圖 瀏覽:534
matlab遺傳演算法旅行商問題 瀏覽:304
將辦公軟體加入加密軟體的進程 瀏覽:724
聯想小新pro14編譯器 瀏覽:462