天天看點

Java軟體架構設計

内容: 開始的架構設計也是最難的,需要調研同類産品的情況以及技術特征,了解目前世界上對這種産品所能提供的理論支援和技術平台支援,再結合自己項目的特點(需要透徹的系統分析),才能逐漸形成自己項目的架構藍圖。

  比如要開發網站引擎系統,就從Yahoo的個人首頁生成工具到虛拟主機商提供的網站自動生成系統,以及IBM Webphere Portal的特點和局限 進而從架構設計角度定立自己産品的位置。

  好的設計肯定需要經過反複修改,從簡單到複雜的循環測試是保證設計正确的一個好辦法。

  由于在開始選擇了正确的方向,後來項目的實作過程也驗證了這種選擇,但在一些架構設計的細部方面,還需要對方案進行修改,屬于那種螺旋上升的方式,顯然這是通過測試第一的思想和XP工程方法來實作的。

  如果我們開始的架構設計在技術平台定位具有一定的世界先進水準,那麼,項目開發實際有一半相當于做實驗,是研發,存在相當的技術風險。

  是以,一開始我們不可能将每個需求都實作,而是采取一種簡單完成架構流程的辦法,使用最簡單的需求将整個架構都簡單的完成一遍(加入人工幹預),以檢驗各個技術環節是否能協調配合工作(非常優秀先進的兩種技術有時無法在一起工作),同時也可以探知技術的深淺,掌握項目中的技術難易點。這個過程完成後,我們就對設計方案做出上面的重大修改,豐富完善了設計方案。

  設計模式是支撐架構的重要元件

  架構設計也類似一種工作流,它是動态的,這點不象建築設計那樣,一開始就能完全确定,架構設計伴随着整個項目的進行過程之中,有兩種具體操作保證架構設計的正确完成,那就是設計模式(靜态)和工程項目方法(RUP或XP 動态的)。

  設計模式是支撐架構的一種重要元件,這與建築有很相象的地方,一個建築物建立設計需要建築架構設計,在具體施工中,有很多建築方面的規則和模式。

  我們從J2EE藍圖模式分類http://java.sun.com/blueprints/patterns/catalog.html中就可以很清楚的看到J2EE這樣一個架構軟體的架構與設計模式的關系。

  架構設計是骨架,設計模式就是肉

  這樣,一個比較豐富的設計方案可以交由程式員進一步完成了,載輔助以适當的工程方法,這樣就可保證項目的架構設計能正确快速的完成。

  時刻牢記架構設計的目标

  由于架構設計是在動态中完成的,是以在把握架構設計的目标上就很重要,是以在整個項目過程中,甚至每一步我們都必須牢記我們架構設計的總體目标,可以概括下面幾點:

  1. 最大化的重用:這個重用包括元件重用和設計模式使用等多個方面。

  比如,我們項目中有使用者注冊和使用者權限系統驗證,這其實是個通用課題,每個項目隻是有其内容和一些細微的差别,如果我們之前有這方面成功研發經驗,可以直接重用,如果沒有,那麼我們就要進行這個子項目的研發,在研發過程中,不能僅僅看到這個項目的需求,也要以架構的概念去完成這個可以稱為元件的子項目。

  2. 盡可能的簡單明了:我們解決問題的總方向是将複雜問題簡單化,其實這也是中間件或多層體系技術的根本目标。但是在具體實施設計過程中,我們可能會将簡單問題複雜化,特别是設計模式的運用上很容易範這個錯誤,是以如何盡可能的做到設計的簡單明了是不容易的。

  我認為落實到每個類的具體實作上要真正能展現系統事物的本質特征,因為事物的本質特征隻有一個,你的代碼越接近它,表示你的設計就是簡單明了,越簡單明了,你的系統就越可靠。更多情況是,一個類并不能反應事物本質,需要多個類的組合協調,那麼能夠正确使用合适的設計模式就稱為重中之重。

  我們看一個具備好的架構設計的系統代碼時,基本看到的都是設計模式,寵物店(pet store)就是這樣的例子。或者可以這樣說,一個好的架構設計基本是由簡單明了的多個設計模式完成的。

  3. 最靈活的拓展性:架構設計要具備靈活性拓展性,這樣,使用者可以在你的架構上進行二次開發或更加具體的開發。

  要具備靈活的拓展性,就要站在理論的高度去進行架構設計,比如現在工作流概念逐漸流行,因為我們具體很多實踐項目中都有工作流的影子,工作流中有一個樹形結構權限設定的概念就對很多領域比較通用。

  樹形結構是組織資訊的基本形式,我們現在看到的網站或者ERP前台都是以樹形菜單來組織功能的,那麼我們在進行架構設計時,就可以将樹形結構和功能分開設計,他們之間聯系可以通過樹形結構的節點link在一起,就象我們可以在聖誕樹的樹枝上挂各種小禮品一樣,這些小禮品就是我們要實作的各種功能。

  有了這個概念,通常比較難實作的使用者級别權限控制也有了思路,将具體使用者或組也是和樹形結構的節點link在一起,這樣就間接實作了使用者對相應功能的權限控制,有了這樣的基本設計方案的架構無疑具備很靈活的拓展性。

  Java架構設計

  軟體架構作為一個概念,展現在技術和業務兩個方面。

  從技術角度來說:軟體架構随着技術的革新不斷地更新其内容,軟體架建構立于目前技術和一些基本原則的基礎之上。

  先說一些基本原則:

  •   分層原則:分層是為了降低軟體深度複雜性而使用的關鍵思想,就像社會有了階級一樣,軟體有了層次結構。
  •   子產品化原則:子產品化是化解軟體廣度複雜的必然手段,子產品化的目的就是讓軟體分工。

  接口實作分離原則随着軟體子產品化的不斷深入改進,面向接口程式設計而不是面向實作程式設計可以讓複雜度日趨增高的軟體降低子產品之間的耦合度,進而讓各子產品更輕松改進。從這個原則出發,軟體也從微觀進行了細緻的規範化。

  還有兩個比較小但很重要的原則:

  細節隐藏原則很顯然把複雜問題簡化,把難看的細節隐去,能讓軟體結構更清晰。其實這個原則使用很普遍,java/c++語言中的封裝原則以及設計模式中的Facade(外觀)模式就很能展現這個原則的精神。

  依賴倒置原則随着軟體結構的進一步發展,層與層之間、子產品與子產品之間的依賴逐漸加深,而層、子產品的動态可插拔要求不端增大。依賴倒置原則可看視為接口實作分離原則的深化,根據此原則的精神,軟體進入了工具時代。這個原則有點類似于知名的好萊塢法則:Don't call us, we'll call you。

  以上這些原則奠定了我們的軟體架構的價值名額。但軟體架構畢竟是建立在目前技術之上的。而每一代技術都有架構模式。過去的不再說了,讓我們現在就來看一下目前流行的技術,以及目前我們能采用的架構。

  因為面向對象是目前最流行開發技術,且設計模式的大量使用使面向對象的走向成熟,而資料庫是目前最有效的存儲結構、web界面是目前最流行的使用者接口,是以目前最典型的三層次架構就架構在以上幾項技術的基礎之上,用資料庫作存儲層、用面向對象來實作業務層、用web來作為使用者接口層。我們從三層次架構談起:

  因為面向對象技術和資料庫技術不适配,是以在标準三層次架構的基礎上,我們增加了資料持久層,來管理O-R雙向映射,但目前一直沒有最理想的實作技術。cmp和entity bean技術因為其實作複雜,功能前景有限,已接近被淘汰的邊緣。JDO及hibernate作為o-r映射的後期之秀,尤其是hibernate,功能相當完備。推薦作為持久層的首選

  在業務層,因為目前業務日趨負載,且變動頻繁,是以我們必須有足夠靈活的技術來保證我們的适應變化的能力,在标準j2ee系統中session bean負責業務處理,且有不錯的性能表現,但采用ejb系統對業務架構模式改變太大,且其複雜而昂貴,業務代碼移植性差。而spring 作為一個bean配置的輕量級架構,漂亮的IOC模式實作,對業務架構影響小,是以推薦作為中間層業務架構。

  在使用者結構層,雖然servlet/jsp/jstl/javaBean 能夠實作MVC架構,但終究過于粗糙。struts對MVC架構的實作就比較完美,Taperstry也極好地實作MVC架構,且采用基于事件的方式,非常誘人,惜其不夠成熟,我們仍舊推薦struts作為使用者接口層基礎架構。

  因為業務層是三層次架構中最有決定意義的,是以讓我們回到業務層細緻地分析一下,在複雜的業務我們常常需要以下基礎服務的一種或幾種:事務一緻性服務acid(tool:jta/jts)、并發加鎖服務concurrent&&lock、池化管理服務cache、通路控制服務 (tool:jaas)、流程控制服務workflow、動态實作服務IOC,串行化消息服務(tool:jms)、負載平衡服務blance等。如果我們不采用重量級應用伺服器(如weblogic,websphere,jboss等)及重量級元件(EJB),我們必須自己實作其中一些服務。雖然我們大多情況下,不需要所有這些服務,但實作起來卻非易事。幸運的是我們有大量的開源實作代碼,但采用開源代碼卻常常是件不輕松的事。

  随着xml作為結構化資訊傳輸和存儲地位日漸重要,一些xml文檔操作工具(DOM,Digester,SAX等)的使用愈發重要,而随着 xml schema的java binding工具(jaxb,xmlbean等)工具的成熟,采用xml schema來設計xml文檔格式,然後采用java binding來生成java bean 會成為主要程式設計模式,而這又進一步使資料中心向xml轉移,使在中小資料量上,愈發傾向于以xquery為查詢語言的xml資料庫。最近還有一個趨勢, microsoft,ibm等紛紛大量開發中間軟體如(microsoft office之infopath),可以直接從xml schema 生成錄入頁面等非常實用的功能。還有web service 的廣泛應用,都将對軟體的架構有非常重大的影響。至于面向服務架構(SOA)前景如何,三層次架構什麼時候走入曆史,現在還很難定論。

  aop的發展也會對軟體架構有很深的影響,但在面向對象架構裡,無論aspectJ還是jboss-aop抑是aspectWerks、 nanning都有其自身的嚴重問題:維護性很差,是以說它将很難走遠。也許作為一個很好的思想,它将在web service裡大展身手。

  rdf,owl作為w3c語義模型的标志性的語言,也很難想象能在目前業務架構發揮太大影響。但如果真如它所聲稱那樣,廣泛地改變着資訊的結構。那麼對軟體架構也會有深遠影響。

  有關架構設計的一些忠告:

  •   盡量建立完整的持久對象層.可獲得高回報
  •   盡量将各功能分層,分塊,每一子產品均依賴假定的其它子產品的外觀
  •   不能依賴靜态資料來實作IOC模式,應該依賴資料特征接口,靜态資料僅是資料特征接口實作方式之一

  架構設計時xml是支援而不是依賴.但可以提供單一的xml版本的實作

  從業務角度說:軟體架構應是深刻展現業務内部規則的業務架構,但因為業務變化頻纴,是以軟體架構很難保持恒定不變,但業務的頻繁變化不應是軟體架構大規模頻繁變化的原因,軟體架構應是基于變化的架構。

  一種業務有其在一段時間内穩定存在的理由(暫且不談),業務内部有許多用例,每一種用例都有固定的規則,每一規則都有一些可供判定的項,每一項從某一次元來觀察都是可測量的,我們的架構首先必須保證完美适應每一項每一種測量方式,很多失敗的架構都是因為很多項的測量方式都發生變更這種微觀變化中。

  每個用例都有規則,我們在作業務用例分析,常常假定一些規則是先驗的,持久穩定的,然而後來的業務改變常常又證明這種看法是錯誤的,然而常常我們的架構已經為之付出了不可挽回的代價。大量事實證明:規則的變化常常用例變化的根本原因。是以我們的架構要盡可能适應規則的變化,盡可能建立規則模版。

  每個用例都關系着不同的角色。每一個用例的産生都必然是因為角色的變更(注意:不是替換,而是增強或減弱),是以注意角色的各種可能情況,對架構的設計有舉足輕重的意義。在我們目前的三層架構裡,角色完美地對應接口概念。

  在一個系統裡很多用例都互相關聯,考慮到每個用例均有可能有不同的特例,是以在架構設計中,盡量采用依賴倒置原則。如架構許可可采用消息通信模式(JMS)。這樣可降低耦合度。

  現在我們談一下業務穩定存在理由對業務的影響。存在即是合理,在這裡當然是正确的。業務因人而存在,是以問業務存在的理由即是問不同角色的需要這項業務的理由以及喜歡不喜歡目前業務用例的理由,所有這樣的角色都應該在系統裡預留。

  在架構設計中有幾個原則可以考慮:

  •   用例盡量細分
  •   用例盡量抽象
  •   角色盡量獨立
  •   項測量獨立原則
  •   追求簡單性

  這裡未提供相關的例子,例子會在以後的更新時提供。

  業務和模式之間的關系

  業務中的一些用例之間的關系常常和一些正常的模式很相似。但随着時間的演化,慢慢地和先前的模式有了分歧。這是個正常的現象。但這對系統架構卻要求非常高,要求系統架構能适應一些模式的更替。在這裡我們盡可能早地注意到用例之間的互相角色變化,為架構更新做好準備.