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


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

 

設計層面:

 

  • 分層架構

分層架構是項目設計中很重要的一點,從根本的目的上來說就是為了職責的分離。最經典的三層架構,到四層五層六層,甚至有人開玩笑說十八層的分層,根據項目的需要可以分不同的層。這里說的層其實是邏輯層,從物理層的角度來說也有三層、四層五層的分層架構。之所以三層架構這么流行是因為它的分層把大的關注點進行了分離,層數恰到好處,表現層、業務邏輯層和數據訪問層,分別處理面向用戶呈現的、面向邏輯處理的和面向數據庫存取數據的三大關注點。

  1. 在分層架構中除了分層之外還需要對每一層都提取出自己需要的模型,比如表現層的視圖模型、業務邏輯層的業務模型或領域模型以及數據訪問層的實體,當然如果還有服務層的話還有服務層的契約或數據傳輸對象。帶來的一個問題就是這些實體或模型之間怎么進行轉換,當然最簡單可靠的辦法就是手寫代碼進行賦值,如果對象中的字段屬性超過10個的話就會讓人崩潰,因此現在有很多映射Mapper類庫可以用來實現各個不同模型之間的轉換。
  2. 分層分的好不好直接影響了系統代碼的清晰性和可讀性。有的人會問,我使用了三層結構無非就是上層調用下層,改了數據庫字段的話還要同時改三層這是多麻煩的事情啊?其實之所以會有這樣的疑問是因為:首先,你的項目不夠大,或者說邏輯實在是太簡單了,導致你的代碼中就是上下級的調用。其次,即使你把所有的代碼都混在了一起,改了數據庫的字段也是需要修改SQL語句的也是需要修改參數校驗規則的也是需要修改界面來多呈現這個字段的,其實要改的東西沒有少改只不過代碼都混在了一起,覺得好像改的地方不多罷了。第三,修改數據庫字段這種操作其實對於一個穩定的系統來說不會經常發生,往往我們會改界面會改邏輯,這樣的話如果有分層我們只需要修改相應層的代碼就可以了,如果每一層是單獨分程序集或分jar包編譯的話,那么我們甚至只用進行組件的替換。
  3. 雖然說三層架構很簡單,但是要真正落實三層架構的分離理念其實不是這么容易的。舉一個例子,同樣是對字段判斷必須是數字的這個操作,應該在表現層寫還是業務邏輯層寫還是數據庫層寫?我們要明確,每一層都只是做自己層職責上的事情,不應該去越權,並且要做的事情一定要做好。首先這個判斷每一層都要進行,表現層腳本和代碼驗證,履行好表現層的職責,業務邏輯層也不能因為表現層驗證了就不驗證,業務邏輯層不關心表現層做了什么,參數不符合類型就提出了,同樣數據訪問層對於數字類型的參數就要確保是數字類型的確保在為參數設置了正確的類型。心理很清楚每一個層需要負責的事情,也要很清楚每一層只關心自己的事情,這樣就能把正確的代碼寫在正確的位置了。

 

  • 高內聚低耦合

高內聚低耦合是一個很重要的設計理念,其實這個理念大家都知道但是怎么樣能讓這個理念在代碼中落實?我覺得可以抓住下面幾個原則,這幾個原則始終記在腦子里面即可:

  1. 任何一個方法都檢查一遍是不是只做了一件事情。如果一段代碼又在做界面展現,又有SQL語句,或是又在處理員工的工資又在處理員工的考勤,那么往往表示這段代碼做了過多不是自己的事情了。它或許應該分成兩個方法,甚至是不同類型的兩個方法。
  2. 任何一個類型都檢查是不是只做了一件事情。這是非常重要的一個檢查,如果一個類型做了太多的事情,很明顯你沒有對類型的職責進行一個明確的划分(當然這個類型就是來負責協調的作為門面類型例外),請檢查類中的所有功能是不是符合類名,如果一個類型叫做NetworkingAdapter而其中有處理XML的代碼的話顯然不合適,是否應該使用其它繼承的類型來處理XML,或者是使用類似於策略模式來處理不同的數據?
  3. 任何一段代碼都檢查是不是只在一個地方出現。這也是非常重要的一個檢查,往往我們可以用這一條金標准來做重構。如果一段代碼在多處出現要么這是一段和業務無關的代碼,可以AOP解決,要么就有大問題了,一段相同的業務邏輯在多個地方出現,一旦業務邏輯有改有多少人知道要改兩個甚至更多的地方,很明顯應該把代碼提取出來封裝在一個地方。
  4. 任何一個類型都檢查是不是依賴過多的類型。除非是門面類型否則一個類型應該不會依賴過多的類型,暫且不說類型的依賴可以通過IOC來解決,如果一個類型依賴了過多的類型,它就會和其它類型進行比較多的強耦合。可以考慮使用門面模式來梳理類型之間的關系,盡量減少和太多的類型之間發生關聯。
  5. 如果一個類型都檢查是不是依賴的類型也同樣依賴自己。如果產生這種雙向依賴的話,建議使用中間人來處理兩個類型之間的依賴,不要讓兩個類型相互調用相互依賴。在有的時候我們可以考慮類型A把數據寫到一個地方,類型B從這個中間點去獲取數據然后進行處理處理后還是把結果存在這個中間點,類型A再從這個中間點獲取結果。這樣的話A和B其實沒有很強的依賴,大家都依賴中間點獲取結果,即使把B替換成C只要它最終輸出的東西是大同小異的那么A就不需要修改。

 

  • 設計模式

所有的設計模式其實都是前人在大量的編程實踐后總結出來的,每一個模式都有適用的地方,每一個模式都是解決一個問題的,因此針對設計模式我的建議如下:

  1. 應該對每一個設計模式都了解,然后你自然可以想到在合適的時候使用合適的模式。
  2. 不要去濫用設計模式,好的設計模式可以增強代碼的高內聚低耦合也可以讓代碼對擴展友好,但設計模式濫用可能會導致代碼的性能問題以及不必要的編碼。
  3. 作為開發gof的設計模式應該熟讀,只是讀還不夠,自己想辦法去在今后的編碼過程中體會應用設計模式,如果一個設計模式沒用那么他就在書上,如果用了那么他就在你腦子里。

 

  • 面向對象

面向對象的三大要素許多人也是熟讀在心了,但是個人認為要徹底明白面向對象三大要素是需要大量OO實踐積累的。對於過程式的開發其實是結果導向的,這比較容易理解。但OO開發其實是維護導向的,通過OOD后開發出來的代碼是比較容易進行擴展的,也是可以支撐復雜業務的。對一套好的OO代碼進行擴展可能門檻會比較高,因為每一個對象都有自己的職責,需要理清楚對象之間的關系,一旦入手了就會發現非常爽的感覺。可以大量利用系統內已經實現的類型,如果繼承和重寫實現自己的需求,然后還可以通過實現接口把自己的實現插到原有的OO體系中去,也就是可能只需要幾行代碼就可以對系統進行改造。對於沒有OO的代碼改造上手不一定很困難,因為代碼很直白,但是一旦進行幾十次改造之后代碼就沒有可維護行了,因為所有的代碼都交織在一起,而且會有大量的硬編碼(面向結果的代碼特點就是可能從上到下很多地方都可以改,而且可以實現相同的效果,一旦這么做了可能就會導致原來的邏輯被破壞,代碼可維護性降低)。對於OO的學習我的體會是:

  1. 可以從設計模式入手,設計模式是OO的一個總結,學習了設計模式有助於理解OO的三大理念。
  2. 可以多閱讀優秀的框架或類庫的代碼,優秀的開源框架一定是對擴展友好的,因此它的設計往往是非常OO的,通過閱讀改造開源代碼可以提升OOD的能力。
  3. 多重構多思考,根據上面提到的高內聚低耦合中說的那些問題想辦法去重構代碼,你會發現很多優化只能通過OO的手段進行,思考重構然后再重構來進步。

 

 


免責聲明!

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



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