• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    敏捷思維(9)—分層 (上)

    發布: 2008-2-02 17:03 | 作者: 林星 | 來源: 不詳 | 查看: 74次 | 進入軟件測試論壇討論

    領測軟件測試網 在定義了架構愿景之后,團隊中的所有人員應該對待開發的軟件有一定的了解了。但是,面對一個龐大的軟件系統,接下來要做些什么呢?分而治之的思想是計算機領域非常重要的思想,因此我們也從這里開始入手。

      要進行應用軟件的設計,分層是非常重要的思想,掌握好分層的思想,設計出的軟件是可以令人賞心悅目的。由于這一章的重要性和特殊性,本章的內容分為上下兩節,并不采取模式描述語言的方式。

      分層只是將系統進行有效組織的方式。 本章特別針對于企業應用進行討論,但其中大部分的內容都可以應用在其它的系統中,或為其它的系統所參考。

      在企業應用中,有兩個非常重要的概念:業務邏輯和持久性?梢哉f,企業應用是圍繞著業務邏輯進行開展的。例如報銷、下訂單、貨品入庫等都是業務邏輯。從業務邏輯的底層實現來看,業務邏輯其實是對業務實體進行組織的過程。這一點對于面向對象的系統才成立,因為在面向對象的系統中,識別業務實體,并制定業務實體的行為是非;A的工作,而不同的業務實體的組合就形成了業務邏輯。

      還有另一個重要的概念是持久性。企業應用中大部分的數據都是需要可持久化的。因此,基礎組織支持持久性就顯得非常的重要。目前最為通行的支持持久性的機制是數據庫,尤其是關系性數據庫-RDBMS。

      除此之外,在企業應用中還有其它的重要概念,例如人機交互。

      為了能夠更有效的對企業中的各種邏輯進行組織,我們使用層技術來實現企業應用。層技術在計算機領域中有著悠久的歷史,計算機的實現中就引用了分層的概念。TCP/IP的七層協議棧也是典型的分層的概念。分層的優勢在于:

      上層的邏輯不需要了解所有的底層邏輯,它只需要了解和它鄰接的那一層的細節。我們知道TCP/IP協議棧就是通過不同的層對數據進行層層封包的,不同層間的耦合度明顯降低。通過嚴格的區分層次,大大降低了層間的耦合度。

      某一層次的下級層可以有不同的實現。例如同樣的編程語言可以在不同的操作系統和不同的機器中運行。

      和第三條類似的,同一個層次可以支持不同的上級層。TCP協議可以支持FTP、HTTP等應用層協議。

      綜合上面的考慮,我們把企業應用分為多個層次。企業應用到底應該分為幾種層次,目前還沒有統一的意見。

      在前些年的軟件開發中,兩層結構占有很重要的位置。例如在銀行中應用很廣的大型主機/終端方式,以及Client/Server方式。兩層的體系結構一直到現在還廣泛存在,但是兩層結構卻有著很多的缺點,例如客戶端的維護成本高、難以實現分布式處理。隨著在兩層結構的終端用戶和后端服務間加入更多的層次,多層的結構出現了。

      經典的三層理論將應用劃分為三個層次:

      表示層(Presentation Layer),用于處理人機交互。目前最主流的兩種表示層是Windows格式和WebBrowser格式。它主要的責任是處理用戶請求,例如鼠標點擊、輸入、HTTP請求等。

      領域邏輯層(Domain Logic Layer),模擬了企業中的實際活動,也可以認為是企業活動的模型。

      數據層(Data source Layer),處理數據庫、消息系統、事務系統。

      在實際的應用中,三層結構有一些變化。例如,在Windows的.NET系統中,把應用分為三個層次:表示層(Presentation Layer)、業務層(Business Layer)、數據訪問層(Data Access Layer),分別對應于經典的三層理論中的三個層次。值得一提的是,.NET系統中表示層可以直接訪問數據訪問層,即記錄集技術。在ADO.NET中,這項技術已經非常成熟,并通過表示層中的某些數據感知組件,實現非常友好的功能。這種越層訪問的技術通常被認為是不被允許的,因為它可能會破壞層之間的依賴關系。而在Windows平臺中,嚴格遵守準則就意味著需要大量額外的工作量。因此,我們看到準則也不是一成不變的。

      在J2EE的環境中,三層結構演變為五層的結構。在表示層這里,J2EE將其分為運行在客戶機上的用戶層(Client Layer),以及運行在服務端上的Web層(Presentation Layer)。這樣做的主要理由是Web Server已經成為J2EE中非常核心的技術,例如JSP和Java Servlet都和它有關系。Web層為用戶層提供表示邏輯,并對用戶的請求產生回應。

      業務層(Business Layer)并沒有發生變化,仍然是處理應用核心邏輯之處。而數據層則被劃分為兩個層次:集成層(Integration Layer)和資源層(Resource Layer)。其中,資源層并非J2EE所關心的內容,它可能是數據庫或是其它的老系統,集成層是重要的層次,包括事務處理,數據庫映射系統。

      實例

      這一章的的組織方式和之前的模式有一些差別。我們先從一個例子來體會架構設計中分層的重要性。

      

      上圖是一個業務處理系統的軟件架構圖。在上圖中,我們把軟件分為四個層次。這種層次結構類似于我們前面所談的J2EE的分層。但是和J2EE不同的是,缺少了一個Web Server層,這是因為目前我們還沒有任何對Web Server的需要。

      在資源層上,我們有三種資源:數據庫、平臺服務、UI。數據庫是企業應用的基礎,而這里的平臺服務指的是操作系統系統或第三方軟件提供的事務管理器的功能。值得注意的是,這里的事務管理器指的并不是數據庫內部支持的事務,而是指不同的業務實體間事務處理,這對于企業應用有著很重要的意義。因為對于一個企業應用來說,常常需要處理跨模塊、跨軟件、甚至跨平臺的會話(Session),這時候,單純的數據庫支持的事務往往就難以勝任了。這方面的例子包括微軟的MTS和Oracle的DBLink。當然,如果說,在你處理的系統中,可以使用數據庫事務來處理大部分的會話的話,那就可以避免考慮這方面的設計了。除了典型的事務管理器,平臺還能夠提供其它的服務。對于大部分的企業應用來說,都是集成了多個的平臺服務,平臺服務對架構的設計至關重要。但是從分層的角度上考慮,上層的設計應該盡可能的和平臺無關。和使用平臺服務類似的,一般來說,企業應用都不會從頭設計界面,大部分情況下都會使用現有的的UI資源。比如Window平臺的MFC中的界面部分。因此,我們把被使用的UI資源也歸到資源層這個層次上。

      資源層的上一層是集成層。集成層主要完成兩項工作,第一項是使用資源層的平臺服務,完成企業應用中的事務管理。有些事務處理機制已經提供了比較好封裝機制,直接使用資源層的平臺服務就可以了。但是對于大多數的應用來說,平臺提供的服務往往是比較簡單的,這時候集成層就派上大用場了。第二項是對上一層的對象提供持久性機制?梢哉f,這是一組起到過渡作用的對象。它實際上使用的是資源層的數據庫功能,并為上一層的對象提供服務。這樣,上一層的業務對象就不需要直接同數據庫打交道。對于那些底層使用關系型數據庫,編程中使用面向對象技術的系統來說,目前比較常見的處理持久性的做法是對象/關系映射(OR Mapping)。

      在這個層次上,我們可以做一些擴展,來分析層的作用。假設我們的系統需要處理多個數據庫,而不同數據庫之間的處理方式有一定的差異。這時候,層的作用就顯示出來了。我們在集成層中支持對多個數據庫的處理,但對集成層以上的層次提供統一的接口。對于業務層來說,它不知道,也不需要知道數據庫的差別。目前我們自己開發了集成層中的持久類,但是隨著功能的擴展,原有的類無法再支持新增加的功能了,新的解決方案是購買商用程序。為了盡可能的保持對業務層次的影響,我們仍然使用原有的接口,但是具體的實現已經不同了,新的代碼是針對新的商業程序來實現的。而對業務層來說,最理想的狀況是不需要任何的改變。當然現實中不太可能出現如此美好的情況,但可以肯定的一點是,引入層次比不引入層次要好的多。

      以上列舉的兩個例子都是很好的解決了耦合度的問題。關于分層中的耦合度的問題,我們在下面還會討論。

      業務層的設計比較簡單,暫時只是把它實現為一組的業務類。類似的,表示層的設計也沒有做更多的處理。表示層的類是繼承自資源層的。這是一種處理的方法,當然,也可以是使用關系,這和具體的實現環境和設計人員的偏好都有關系,并不是唯一的做法。在對軟件的大致架構有了一個初步了解之后,我們需要進一步挖掘需求,來細化我們的設計。在前面的設計中,我們對業務層的設計過于粗糙了。在我們的應用中,還存在一個舊系統,這個系統中實現了應用規則,從應用的角度來看,這些規則目前仍然在使用,但新的系統中會加入新的規則。在新系統啟用后,舊的系統中的規則處理仍然需要發揮它的作用,因此不能夠簡單的把所有的規則轉移到新系統中。(有時候我們是為了節省成本而不在新系統中實現舊系統的邏輯)。我們第二步的架構設計的細化過程中將會加入對新的要求的支持。

      在細化業務層的過程中,我們仍然使用層技術。這時候,我們把原先的業務層劃分為兩個子層。對于大多數的企業應用來說,業務層往往是最復雜的。企業對象之間存在著錯綜復雜的聯系,企業的流程則需要用到這些看似獨立的企業對象。我們希望在業務層中引入新的機制,來達到組織業務類的目的。業務層的組織需要依賴于具體的應用環境,金融行業的應用和制造行業的應用就有著巨大的差距。這里,我們從一般性的設計思考的角度出發來看待我們的設計:

      

      首先,我們看到,業務層被重新組織為兩個層次。增加層次的主要考慮是設計的重用性。從我們前面對層的認識,我們知道。較高的層次可以重用較低的層次。因此,我們把業務層中的一部分類歸入較低的層次,以供較高的層次使用。降低類層次的主要思路是分解行為、識別共同行為、抽取共性。

      在Martin Fowler的分析模式中提供了一種將操作層和知識層分離的處理方法:

      

      Action、Accountability、Party屬于較高層次的操作層(Operational Layer),這一層次的特點是針對于特定的應用。但是觀察Accountability和Party,有很多相似的職責。也就是說,我們對于知識的處理并不合適。因此,Martin Fowler提出了新的層次――屬于較低層次的知識層(Knowledge Layer)。操作層中可重用的知識被整理到知識層。從而實現對操作層的共性抽取。注意到雖然圖中的層次(Level)的概念和層(Layer)有所差別,但是思路是基本一致的。

      另一種分層方法是利用繼承:

      

      該圖中也是來自于分析模式一書。不同的部門有著差異點和共性,將共性提取到父類中是繼承的基本概念。這時候我們可以把父類看作是較低的層次,而把子類看作是較高的層次。對于一組層次結構很深的類來說,也可以從某一個水平線上分離層次。

      最后一種方法需要分解并抽象對象的行為。C++的STL中為不同的數據類型和不同的容器實現了Iterator的功能。它的實現是典型的降低層次的行為。我們不考慮它對不同數據類型的支持,因為它使用了比較獨特的模板(Template)技術,只考慮它對不同的容器的實現。首先是對共性的分析,不論是數組(Array)還是向量(Vector),要執行遍歷操作,都需要知道三個條件:容器的起始點、容器的長度、匹配值。這就是一種抽象。通過這種方式,就可以統一不同容器的接口。

      以上我們討論了細分層次的好處和實現策略。下面我們回到前例中,繼續討論層中的各個部件。

      業務實體指的是企業中的一些單獨的對象。例如訂單、客戶、供應商等。由于業務實體可以被很多的業務流程(業務會話)所使用,因此我們把業務實體放在業務實體層中。企業中的業務實體大多是需要持久性的。因此在我們的設計中,業務實體將持久性的職責委托給下一個層次中的持久性包,而不是直接調用數據庫方法。另一種常用的方法是使用繼承――業務實體繼承自持久類。EJB中的Entity Bean就是典型的業務實體,它可以支持自動的持久性機制。

      在我們的系統中,規則是一個尷尬的存在。部分的規則處于舊系統中,并使用舊系統的持久性機制。而新系統中有需要支持新的規則。對于上層的用戶來說,并不需要知道新舊系統的規則。如果我們在使用規則時做一個新舊規則的判斷并調用不同的系統函數,那就顯得太傻了。我們的設計對上層而言應該是透明的。

      所以我們總共設計了三個包來實現規則的處理。包裝器包裝了舊系統中的規則,這樣做處于幾點考慮:首先,舊系統是面向過程的,因此我們需要用包裝器將函數(或過程)封裝到類中。其次,對舊系統的使用需要額外的程序(或平臺服務)的支持,因此需要單獨的類來處理。最后,我們可以使用Adapter模式[GOF 94]將新舊系統不同的接口給統一起來,以使他們能夠一起工作。新的規則類實現了新的規則,較好的做法是定義一個虛協議,具體的表現形式可以是虛基類或接口。然后由其子類實現虛協議。再結合前面介紹的把舊規則的接口轉換為新的接口的方法,就能夠統一規則接口。從圖中我們看到,業務實體需要使用規則,通過統一的接口,業務實體就能夠透明的使用新舊兩種規則。

      在定義了規則和標準的規則接口之后,上一層的規則控制器就可以通過調用規則,來實現不同規則組合。因此這個規則控制器就類似于應用規則。在業務交易處理中需要調用規則控制器來實現部分的功能。

      請注意,這里討論的思路雖然非常的簡單、清晰,但是現實中的處理卻沒有這么容易。因為為新舊規則制定統一的接口實在是太難了。要能夠使接口在未來也相對的穩定更是難上加難。而在應用已經部署之后,對已發布的接口的任何一個小改動都意味著很高的成本。在這個問題上,并沒有什么好的策略,經驗是最重要的。在實際中的一個比較實用的方法是為接口增加一些額外的參數。即便可能這個參數當前并沒有使用到,但是如果為了有可能使用的話,那還是加上吧。舉個例子,對于商業應用軟件而言,數據庫,或者說是關系數據庫一定是不可缺少的部分。大量的操作都需要和數據庫結合起來,因此,可以考慮在方法中加入一個數據庫連接字符串的參數。雖然這對于很多方法而言是沒什么必要的,但是為將來的實踐提供了一個可擴展的空間。國內的某個知名的ERP軟件的設計就采用了這種思路。

      本章的主要精力都放在實例的研究上,在有了一個基本的概念之后,我們再回來談談分層的一些原則和需要注意的問題。

      (待續)

      作者簡介:

      林星,辰訊軟件工作室項目管理組資深項目經理,有多年項目實施經驗。辰訊軟件工作室致力于先進軟件思想、軟件技術的應用,主要的研究方向在于軟件過程思想、Linux集群技術、OO技術和軟件工廠模式。您可以通過電子郵件 iamlinx@21cn.com 和他聯系。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/

    TAG: 敏捷思維


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>