我的架構經驗系列文章 - 后端架構 - 框架層面


回到索引 http://www.cnblogs.com/lovecindywang/archive/2012/12/23/2829828.html

 

框架層面:

 

  • SOA

在這一篇中會逐個介紹一下自己對這些XXX的理解,其實每一個理念都不是莫名其妙產生的而是有產生背景的,這些時髦的名詞不是用來炫耀的,而是真正要理解它們是干什么的,並且框架千萬不能亂用理念也千萬不能亂用,並不是把所有的這些都用上你的系統才是一個牛逼的系統,一定要適合才是最好的,並且要保持簡單可靠的原則。所謂SOA,字面上來說是面向服務的架構。有的人不說SOA其實他已經SOA了,有的人大談SOA但其實只是在用Web服務,SOA可大可小。你可以認為服務調用就是SOA了,也可以認為服務調用只是SOA中的很小一部分。個人覺得SOA的理念是說,把業務邏輯從類庫的封裝提升到服務的封裝,並且通過不同的信道不同的編碼格式來提供服務,使異構系統之間也能重用服務,說白了就是讓代碼從本機重用提升到了跨機器的重用。從最簡單的來說,把組件封裝成自制的服務,通過交換消息來使用服務提供的功能,那么就是SOA了,但這也僅僅是SOA的開始,比如你是否想過下面的問題怎么解決?

  1. 你的服務是否可以被外部的異構系統使用?
  2. 如果你的服務又需要調用另外的服務,怎么處理復雜的調用關系,怎么監控整個調用過程?
  3. 服務調用怎么納入事務的控制中?
  4. 服務越來越多,接口越來越多,怎么知道應該調用哪個服務哪個接口?
  5. 接口的版本升級了怎么辦?
  6. 服務有太多人調用,怎么進行負載均衡,怎么限制調用人數?
  7. 怎么做安全,限制服務的匿名調用?
  8. 服務怎么進行測試?
  9. 服務調用失敗后怎么辦?
  10. 服務怎么進行升級和重新部署?

因此,SOA其實不僅僅是調用服務,在監控和治理上有很多事情要做,SOA可大可小。不管怎么說,從理念上來說,SOA確實是一種進步,復雜邏輯都封裝成服務,一個復雜的系統可能調用不同的服務就可以完成了,每一個服務都是自治的,很好的降低了系統整體的復雜度。其實一個復雜的系統如果復雜度在10000的話,那么分成四層實現10*10*10*10就可以大大降低復雜度,每一層只要做好10復雜度就好了,由上層來調用下層。OSI如果不是七層模型,而是一層模型的話很難想象怎么去處理整個復雜的過程。

 

  • RPC

字面上來說就是遠程過程調用,RPC(這里我們說廣義上的RPC)也可以是SOA實現的一種方式,SOA並不一定都通過Web服務實現。從實現原理上來說RPC其實並不是很復雜,無非就是客戶端有一個代理,收集客戶端要調用的遠程方法以及參數,然后序列化成消息提交到遠程,到了遠程之后把消息反序列化,動態執行客戶端所需要的方法(當然也包括創建對應的對象),然后把結果通過另外一個消息返回給客戶端,當然其中的細節太多了。從客戶端和服務端交換數據依賴的信道來說一般使用TCP或HTTP,也可能會是UDP。

  • ORM

對象關系映射解決面向對象系統和數據庫阻抗不匹配的問題,大家都知道的ORM的定義。這里我想說的是ORM的出發點是好的,而且在某些應用中ORM確實可以改善代碼可讀性,增加編碼效率,個人認為ORM是有使用情況的,不是所有的數據訪問都適合使用ORM框架的,Java的SSH也有那么一點誤導,Struts不是實現MVC的唯一方法,Spring不是實現IOC的唯一方法,Hibernate也不是實現數據訪問的唯一方法,我覺得ORM:

  1. 它適合領域復雜的,表多的,表之間關系多的,訪問量相對較小的,企業應用。
  2. 它不適合業務相對簡單,表之間關系不多,訪問量超大的互聯網應用。

對於ORM來說要入門是簡單的,但是要用好不是這么容易的:

  1. 如果沒有正確使用很可能導致產生大量的SQL語句,而使用者還不知道。
  2. 如果沒有正確使用很可能會拉取過多不必要的數據,而使用者還不知道。
  3. 如果沒有正確使用很可能會產生性能不高的SQL語句,而使用者還不知道。

因此,即便是使用ORM也要對ORM產生的SQL語句張一個心眼,並且我們需要了解ORM中是如何做延遲加載、級聯加載、主鍵緩存的,只有了解了這些機制才能真正用好ORM,如果對ORM不熟悉,如果在做互聯網系統我覺得還是太平點吧,SQL語句精准高效。當然有的人要說了用SQL的話業務邏輯就可能不在代碼中了,其實這個還是看SQL語句怎么寫的,如果把SQL只是當做數據庫和程序的溝通橋梁的話這不是問題,如果在SQL里面做一些判斷做一些計算那就是自己的事情了。

 

  • IOC

控制反轉依賴注入不是嘴上說說的,它是一個非常實用的理念。有的人即使在使用了IOC之后還沒有意識到為什么要使用IOC,我總喜歡在面試的時候問為什么要用容器來創建對象,自己手動new出來有什么不好?有的人回答是手動new出來的性能不高,容器創建的是唯一的對象,那我就會問自己寫一個單例的對象也是一樣的,為什么要容器創建?其實這樣的理解是有誤的。個人認為管理對象的生命周期只是IOC容器的一個作用,IOC容器的意義在於:

  1. 管理了對象之間的關系。在OO中組合很有用,如果對象之間有復雜關系的話,那么我們就必須在new對象的時候來構建這種關系,這些關系其實都寫死在代碼中了。並且我們通過代碼會直接把實際的類型寫死,降低了針對接口編程的意義。如果能在配置文件中根據自己的需求來配置這種關系,由容器動態創建對象和對象之間關系的話,那么我們就把代碼中依賴提取到了外部,由外部注入進去。在一個分層的應用程序中,我們不僅僅注入平行層級的對象,還可以注入下級對象,實現從上到下的自動注入,整個系統就非常靈活。
  2. 管理了對象的生命周期。有的時候出了單例或是new出來的對象,還會有根據線程、根據請求來的特殊聲明周期的對象,如果手寫代碼來管理聲明周期一來很麻煩,二來也不方便調整,通過容器來管理對象的聲明周期簡單高效,並且我們很容易對容器進行擴展提供不同的聲明周期的字典即可擴展生命周期的類型。

 

  • AOP

面向切面編程對於職責分離和提高可測試性都很重要。一般來說代碼有兩種方式織入,靜態的和動態的。所謂靜態的就是在編譯之前直接改了要包裝的類,然后把關注點的入口方法封裝進去一起編譯的編譯時增強。所謂動態的就是在運行的時候動態修改代碼動態編譯的運行時增強。一旦有了AOP,那么我們的事務、日志、權限、緩存之類和業務無關的代碼就可以不出現和混在業務代碼中了,根據需要進行配置就可以對任意的代碼進行這些橫切關注點的增強。一旦這些代碼有修改,我們也只需要修改配置,而不是在代碼中的幾千個幾萬個地方去查找修改。

 

  • MVC

MVC對於網站特別是互聯網網站來說是一種非常好的里面,MVC的優點體現在:

  1. 職責分離,不再是所有的代碼都混在一起了,V和C的分離尤其重要。
  2. 職責分離早就了可以進行單元測試,可測試性也是重要的一環,對C可以進行單元測試是非常重要的。
  3. 大多數MVC框架都提供了AOP的織入點,在實現職責分離的時候還能實現橫切關注點的自動執行和可替換性。

在實現MVC的時候我們不僅僅是能把MVC框架用上去就好了,要盡可能實現:

  1. C中的諸如緩存、權限、日志之類的橫切關注點務必提取出來通過AOP實現,不要和C的其它業務性邏輯混在一起。
  2. C中的Action可以重用的盡量重用,Action的結果可以重用的也盡量重用。
  3. 可以考慮MVC和IOC相結合,把C用到一些服務或DAO動態注入進來。
  4. 對於V盡量確保V中不要有后端代碼,V可以讓前端開發直接編輯,由后端開發嵌入比較簡單的Tag。如果VM明確的話,前端甚至可以直接寫V。

 

  • TDD

測試驅動開發又是一個不小的概念。各種平台也有各種框架來實現Mock來實現單元測試。工具再好沒有正確的編碼理念也是沒用的,要實現所有的代碼都能通過單元測試來驗證必要的幾個因素包括:

  1. 程序沒有很復雜的上下文環境,或者說上下文環境是可以被模擬的,否則怎么測試?
  2. 程序模塊的職責是單一的清晰的,如果一個模塊做了幾十件事情,有幾百個分支的話是很難測試,測試的粒度越是細越是容易測試。

針對現在大多數項目無法進行TDD,甚至無法進行單元測試的原因是因為往往時間很趕,只能有時間實現最基本的業務邏輯,而單元測試其實編碼的時間不會比實際的編碼少的,甚至更多。個人認為可以根據項目的性質不同來看,如果這個項目本來就是CRUD的,或者是一個臨時的項目,單元測試TDD的意義不大。但如果這個項目是一個要被很多人使用的類庫或者框架性質的項目,沒有單元測試是無法想象的:

  1. 如果一個類庫提供了100個功能,你不可能在修改了一個點之后就去手動測試一下這100個功能,必須通過自動化的手段進行。
  2. 類庫需要確保在所有的邊界情況都考慮到,手動測試或者黑盒測試是很難覆蓋所有情況的。
  3. 如果你的類庫沒有提供單元測試,類庫的使用者怎么在他們的執行環境來驗證類庫的可用性呢?因此還不僅僅是給自己用,別人還要使用你的單元測試來確保類庫在自己的運行環境下可以正常工作。

 

  • 其它

在這里先想總結一下,個人覺得這么多XXX中最需要有的就是MVC和IOC了,至於AOP有了當然更好,至於ORM和SOA則是看需求了,對於TDD么如果你在寫一個類庫或框架那是必須的,否則很難想象這套代碼的穩定性會有多高。除了上面提到那那些XXX其實還有很多作為基礎框架需要實現的東西,以前畫過一個腦圖參考http://www.cnblogs.com/lovecindywang/archive/2012/01/11/2318973.html。作為框架我覺得有一些要素是需要滿足的:

  1. 盡量保持框架對外的接口是很簡單的,復雜的東西應該在框架內部處理掉,對框架的使用者透明。
  2. 框架的異常處理要完善,日志記錄要完善,框架由於是對開發者透明的,因此最好在異常信息和日志信息中寫明要調用者和框架的使用者怎么樣去做才能解決這個問題而不是僅僅是說出了什么錯。
  3. 一個完善的框架應該內建性能檢測機制,或者提供http的接口可以讓外部了解到框架內部的運行狀況。
  4. 框架要做好測試,確保在不同的線程環境和不同的配置情況下框架都能正常運行。
  5. 框架最好有性能測試,讓使用者明確這個框架能提供的性能,以便正確判斷是否可以滿足自己的需求。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM