RichFaces自動構建樹實現

樹形結構在軟件系統中是使用頻率非常大的一種數據結構,包括一些算法的實現也是基於樹形結構來進行的,比如基於二叉樹的二分查找法等等。在軟件系統中,樹形結構更多的體現在樹形菜單的構建上。對於樹形結構我們都能抽取出一個統一的類結構。比如:

Java代碼
  1. public class TreeNode{   
  2.     private String value;//樹節點的值   
  3.     private String label;//樹節點顯示標籤   
  4.     private boolean leaf;//是否是葉子節點   
  5.     private TreeNode parent;//父節點   
  6.     private List<TreeNode> childern;//孩子結點集合   
  7. }  

  通過這個簡單的結構我們就能構建一個最基本的樹。當然我們使用richfaces,它已經給我們提供了這樣的樹形結構接口和默認的實現類。我們可以通過使用默認的實現類來構建樹,也可以實現它的接口來自定義一個樹。

  在OECP系統中,無可避免的存在着大量的樹形結構,最典型的就是組織結構,這些樹形結構充斥在系統的各個角落,作爲最常用的,也是非常通用的結構和實現方式,我們需要一個統一的規劃和設計來處理,以便減少程序員重複的代碼編寫,既可以提供未來開發的效率同時也降低了維護的成本。RichFaces提供的<t:tree>已經是一個高度集成的樹形結構UI,我們在UI層上的工作除了把類似於組織機構這樣常用的組件封裝成統一的標籤調用之外,我們不需要再做額外的處理。我們需要在數據結構的統一構建上做些文章。在構建之初,我們面臨着幾個問題。

  1、 返回樹形結構的數據是不是業務組件的工作,需不需要考慮UI
  2、 是一次完成構建樹還是動態構建樹

  針對第一個問題,我認爲返回樹形結構的數據是不是屬於業務範疇很難界定,但是業務組件不應該綁定UI組件,應該是客戶端技術無關性的,這就造成業務組件即使封裝了樹形結構的數據,在UI表現上仍要針對UI組件進行一次樹與樹的轉換,這無疑增加了兩端的開發量,造成無謂的消耗。所以,我們不考慮在EJB業務組件端進行樹形結構的數據封裝,而是直接返回相應的列表。

  針對於第二個問題,我們考慮到我們使用技術體系,選擇了一次完成構建樹。爲什麼選擇這種方案,有什麼優缺點呢?影響EJB分佈式系統性能的關鍵是分佈式調用帶來的網絡資源的消耗,要降低這種消耗,就要減少對分佈式組件的調用。一次性返回所有的數據就是要減低這種調用EJB的頻率。同時一次性構建樹,在構建樹的工具類中,我們只需要處理這個List就可以了,而無須再次理會調用EJB,適合封裝成統一的、適當通用的組件。但是構建過程可能比較麻煩,如果List中包含的實體類的結構不一致,構建的過程更復雜。動態構建樹在書寫上會比較簡單,但是需要EJB組件提供更多的接口,而且由於構建過程中要不斷調用EJB,所以很難和EJB調用解耦,無法工具化處理。同時,在OECP項目中,所有的實體類都進行了統一的規劃設計,抽象了統一的基礎結構和操作,這給我們統一構建樹帶來了更大的方便。

  現在開始介紹基於RichFaces樹的封裝。
  先看看樹形結構效果圖:

  頁面代碼片段:

XML/HTML代碼
  1. <rich:tree style="width:300px"  
  2.                         value="#{resourceRegisterAction.resourceTree}" var="item"  
  3.                         switchType="client" ajaxSubmitSelection="true"  
  4.                         reRender="info,create,popMsg"  
  5.                 nodeSelectListener="#{resourceRegisterAction.processSelection}"  
  6.                         ajaxKeys="#{null}">  
  7.                         <rich:treeNode>  
  8.                             <h:outputText value="#{item.name}" />  
  9.                         </rich:treeNode>  
  10. </rich:tree>  

注:#{resourceRegisterAction.resourceTree}要實現Richfaces提供的TreeNode接口的實現ajaxSubmitSelection="true"說明是AJAX的提交方式,reRender="info,create,popMsg"這個很重要,表明該操作返回的數據要渲染的組件,比如回填Form,該處需要Form的ID,這樣才能保證數據回填到特定的Form上,否則頁面數據不變化。選擇樹節點需要進行相關的操作,就必須實現nodeSelectListener。
Action構建樹代碼:

Java代碼
  1. public TreeNode<FunctionResourceEO> getResourceTree() {   
  2.             if (resourceTree == null) {   
  3.                try {   
  4.                 List<FunctionResourceEO> list = ResourceServiceDelegate   
  5.                         .getInstance().getAllResources();   
  6.                 FunctionResourceEO func = new FunctionResourceEO();   
  7.                 func.setName("功能資源");   
  8.                 resourceTree = new RichTreeConverter<FunctionResourceEO>()   
  9.                         .list2tree(list, func);   
  10.               } catch (Exception e) {   
  11.                   e.printStackTrace();   
  12.               }   
  13.           }   
  14.             return resourceTree;   
  15. }  

  通過ResourceServiceDelegate.getInstance().getAllResources()得到所有的功能資源信息,EJB端只需要將所有的資源列表返回即可,簡化了EJB組件數據運算以外的操作。最關鍵的是new RichTreeConverter<FunctionResourceEO>().list2tree(list, func);通過這個工具類將list轉化成RichFaces樹的數據結構。該構造過程採用深度優先遍歷算法,在效率上還需要改進,希望大家能批評指正。限於篇幅是該工具類的代碼和實體抽象類的代碼請下載下面的pdf文件進行閱讀。

  希望該RichFaces自動構建樹實現能帶給各位朋友以拋磚引玉的作用,有什麼問題可以寫下您寶貴的留言,大家一起探討共同進步,謝謝!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章