熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

如何在代碼中自動實現設計規范(組圖)

2022-06-13   來源: Java核心技術 

  摘要
  
  設計規范只表示純粹的想法但項目的成功來說實現這些規范是必須的傳統的實現方式是代碼評審Hammurapi是一個遵循設計的工具提供了自動而且一致的方式來實現設計規范因此使代碼評審更加有效而輕松在這篇文章中作者介紹了Hammurapi的使用並與其他類似工具進行比較最後還給出演示如何使用的例子
  
  作為一個JEE架構師我需要分發詳細設計給項目團隊通過UML模型我也會分發那些捕獲最佳實踐的設計規范例如在Struts應用中我推薦避免在Action類中使用實例變量因為Action類是單例的而且多個線程同時訪問一個Action類實例是很平常的其他例子如在任何DAO應用中一個重要的設計方針是關閉所有打開的數據庫資源如果沒有這麼做通常將導致災難尤其是在一個產品環境中
  
  想法是很好的但是實現才是關鍵現在最常用的實現設計規范的方法是做代碼評審通常是有經驗的成員檢查代碼來找出不符合規范的地方這些代碼可能是沒有遵守編碼規范或者設計規范
  
  這是一種非常低效的方法主要表現在兩方面這需要兩種資源(開發人員和評審人員)質量變成評審人員的職責此外在我的經歷中由於評審人員過於重視規范使得他們與開發人員對立起來而這對一個團隊來說是不好的
  
  許多年前我接觸過Checkstyle這是一個自動強制代碼規范的工具他與Ant無縫集成並且由基於XML配置文件來驅動
  
  Hammurapi是一個與Checkstyle類似的工具只是他用來強制設計規范Hammurapi是一個由Pavel Vlasov開發的開源軟件他可以基於一套設計規范來分析代碼庫當他遇到違反規范的地方會在報告中標識就像Checkstyle一樣他與Ant無縫集成並且由基於XML配置文件來驅動
  
  運行Hammurapi
  
  你可以直接從命令行運行Hammurapi或者作為Eclipse的插件來使用在這篇幅文章中我主要討論如何通過Ant任務來運行Hammurapi
  
  注意你可以從資源中下載與本文對應的源程序
  
  與Ant集成非常容易如下面代碼所示
  
    <target name=design_review depends=init>
  <taskdef name=hammurapi classname=orghammurapiHammurapiTask>
  <classpath>
  <fileset dir=${hammurapihome}\lib>
  <include name=**\*jar></include>
  </fileset>
  </classpath>
  </taskdef>
  <hammurapi>
  <src dir=src/>
  <output dir=docs\review/>
  <classpath>
  <pathelement location=${$logjhome}\lib\logjjar\/>
  <pathelement location=${weblogichome}\lib\weblogicjar\/>
  </classpath>
  </hammurapi>
  </target>
  
  第一行定義了一個design_review的目標他依賴於init目標—初始化構建的屬性(如第四行的${hammurapihome})第二行定義了一個hammurapi新任務這個Ant任務由orghammurapHammurapiTask類實現內嵌的classpath元素定義了定義這個任務所需要的類庫
  
  第九行聲明了一個先前定義的hammurapi任務運行這個任務相當簡單只要定義內嵌的src元素就可以了他會告訴任務上哪兒查找源程序然後定義另一個元素output這告訴任務在哪兒輸出報告第十行告訴任務在項目任務目錄下的src目錄下查找需要評審的源程序第十一行告訴任務輸出報告到項目目錄下的docs\review中
  
  第十二行的classpath元素是可選的他定義了源程序依賴的類庫位置
  
  Hammurapi帶有多個內建的檢查器每一個對應一個設計規范
  
  先前列出的Ant代碼片斷將在logj源程序上運行Hammurapi代碼將被解壓到項目目錄下的src目錄顯示了生成的報告的打開頁面Hammurapi最令人激動的特性就是他生成的全面的報告
  
 educitycn/img_///jpg >

  圖例示了報告l的主頁右邊的框架顯示了三個標題結果嚴重性小結和文件
  
  結果段落顯示整體評審的統計如圖中所示個包中的個文件被評審了其中包含違反規范的地方
  
  嚴重性小結段落以表的方式來顯示違反規范的地方每一項屬於一個嚴重級別預定義的級別包含級別是最嚴重的
  
  文件段落(圖)列出了每一個被評審的文件和他所違反的規范
  
 educitycn/img_///gif >

  雖然嚴重性小結段落可以回答如多少空catch塊被找到文件段落可以回答在Appenderjava中多少規范被違反但是Hammurapi最有用的功能是他可以在報告中顯示違反規范所在的代碼行數如讓我們分析一下設計規范ER空catch塊(圖點擊數字列的超鏈就可以顯示報告這個違反的文件如圖所示
  
 educitycn/img_///gif>

  在很多文件中報告顯示LogRecordjava ()在第行違反了這個規范在行數下的超鏈直接鏈接到源程序如圖的示
  
 educitycn/img_///gif >

  雖然從整個代碼庫的運行Hammurapi是最常用的方式但你也可以使用增量的評審自上一次評審後改變的代碼這在代碼庫非常大評審需要很長時間時非常有用
  
  另一個運行Hammurapi的有效方式是可以處理壓縮文件和其所依賴的並生成壓縮的結果文件這種方式在開發團隊分布在不同的地理位置時非常有用在這個情況下源程序被壓縮並傳送到遠程的評審點
  
  其他設計評審工具
  
  Hammurapi並非是僅有的代碼評審工具Metrics也是一個可以作為Eclipse的很流行的類似工具然而他有兩個主要的缺點首先他和Eclipse緊密結合想要與Ant結合相當麻煩由於需要Eclipse的類庫這使得不使用Eclipse作為IDE的項目不能使用Metrics其次你不能用Metrics構造自定義的檢查器(Hammurapi可以)這限制了用戶只能使用內建的檢查器
  
  其他的工具還有PMD類似於Hammurapi他與Ant無縫集成而且允許自定義檢查器然而PMD生成的報告不如Hammurapi生成的報告全面
  
  Hammurapi如何工作
  
  Hammurapi這樣的代碼分析工具都帶有語言分析器語言分析器是一種輸入語言代碼並輸出抽象語法樹的工具這個樹上的節點代表語言標識例如考慮一下簡單的算術表達式+ 語言分析器會解析他成為一個如圖所示的語法樹在這個樹中節點+代表操作符標識節點是操作數標識
  
 educitycn/img_///jpg>

  Hammurapi使用ANTLR(另一個語言識別工具)作為語言分析器然而ANTLR API是相當底層的為改善可用性Hammurapi使用另一個API基於ANTLR 的JSEL(Java源程序工程類庫)來訪問抽象語法樹
  
  一旦樹構建完成一種樹遍歷算法就被用來訪問樹中每一個節點每次訪問到一個節點一種回調機制(Visitor模式)被用來提示相應的檢查器在這些回調方法中檢查器收集相關的信息來確定是否有違反規范的地方存在
  
  構建自定義的檢查器
  
  一個自定義檢查器可以更好理解Hammurapi框架如前面所提一種Struts的最佳實踐是避免Action類中的實例變量所以我們會構建一個自定義檢查器ActionClassInspector他掃描源程序中的Action類如果一個Action類被發現他就掃描是否存在實例變量如果一個以上的實例變量被發現他就標識出相應的違反
  
  圖例示了ActionClassInspector類的變量和方法所有的檢查器都繼承自orghammurapiInspectorBase類
  
 educitycn/img_///jpg >

  圖例示了Hammurapi框架激活ActionClassInspector類的回調方法的時序圖框架解析源程序並構建一個抽象語法樹然後訪問樹中的每一個節點當一個類節點被訪問時他調用visit( v:VariableDefinition )方法因為通常一個類可能包含多個變量這個方法可能會被調用多次
  
educitycn/img_///jpg>

  下面的代碼顯示了visit( c:Class )方法
  
    public void visit( compavelvlasovjselClass c ) throws Exception
  {
  isActionClass = cisKindOf( orgapachestrutsactionAction);
     return;  }
  
  這個方法負責確定是否一個特定的類是Action類這個測試在第三行被執行如果測試是肯定的那麼isActionClass被設置為真這個規范僅應用於Action類
  
  下面的代碼例示了visit( v:VariableDefinition )方法
  
    public void visit( compavelvlasovjselVariableDefinition v ) throws Exception
  {
  List modifiers;
  Scope scope;
  if( thisisActionClass )
  {
  modifiers = vgetModifiers( );
  scope = vgetEnclosingScope( );
  if( scope instanceof compavelvlasovjselimplClassImpl )
  {
  if( ntains( static ) )
  {
  ;//Do nothing; this class is compliant
  }
  else
  {
  contextreportViolation( (SourceMarker)d Violation ); From:http://tw.wingwit.com/Article/program/Java/hx/201311/25636.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.