1. 程式人生 > >關於Django Web應用架構設計開發的幾個問題

關於Django Web應用架構設計開發的幾個問題

依賴 實際應用 解決辦法 會有 簡單的 upd 嵌套 有用 缺點

1、關於分層,做過傳統JEE應用的同學肯定知道JEE應用會分很多個設計層。根據傳統Web應用架構設計一般從上到下分這麽幾個層(太懶了,不畫圖了):Web前端層、Web後端交互層、業務層、基礎數據設施層,Web前端層在瀏覽器裏面由JavaScript來做,暫時不表,數據設施層,Django的數據操作接近Active Record模式,相當完善,基本不用再做封裝加工,重點談談交互層和業務層,交互層主要接受請求數據,調用業務邏輯完成用戶交互.

2、關於業務層的獨立存在問題,Django中業務層獨立有沒有必要,說實話,我剛開始用它做互聯網應用的時候,一是互聯網場景都是弱業務弱事務環境:業務邏輯比較簡單,二是Django的的數據設施層非常完善,用來直接做交互層,代碼量也很小,但是在產品系統不斷發脹的過程中,系統的規模和結構不斷復雜化的過程中,對系統結構管理的要求就會逐漸浮現出來,這個時候對業務層獨立實現的設計要求就會逐漸明顯。產品是變化的,系統是變化的,業務層獨立化重構的要求是在變化的場景下逐漸出現的,當然有的系統一步到位的要求比較高,也許從剛開始就得做獨立的業務層。

3、業務層的設計實現問題,Django中的業務層以什麽樣的方式存在,首先企業應用架構模式中說Active Record模式下的業務層應該和Models放在一起.其次Django其實提供了一種標準的業務層實現方式,就是對models.Manager做擴展,然後把其實例傳給Model類的objects對象.這種方式的好處是,直接從Model類的引用可以調用到業務邏輯方法,缺點是,它和具體Model類的連接有點過於緊密,對於涉及多Model類的業務邏輯,其實也可以在Models模塊中直接以函數的方式來定義.

4、交互層做了什麽,首先Django中的輸入驗證是在表單類定義代碼中完成,簡單的CreateUpdate操作也可以用表單的save直接完成,那麽之前講到交互層要調用業務層的問題,其實都是業務邏輯相對復雜情況下的行為,關於調用,方法調用自然要傳參,在交互層實現Form表單對象的初始化和輸入驗證通過後,把表單對象傳給業務層是比較適合的,1是表單的數據是經過清洗過濾處理的,2是傳遞一個表單對象,這樣的效果類似的JEE中的DTO,傳參處理比較幹凈。

5、事務層放在哪兒,在業務邏輯涉及到多次數據讀寫的時候,事務特性還是很重要的,首先Django提供的事務特性使用方式比較多樣化,首先用事務裝飾view函數是一個一勞永逸比較懶的做法,其次事務的本質其實是和業務有關系的,在業務層方法上添加事務裝飾,是一種更嚴格的設計實現。這種嵌套的多級事務在Django事務特性中完美支持。

6、關於異常處理,首先Django本身提供500錯誤頁面機制,也就是說異常出錯以後的轉向頁面顯示我們不用管,我們需要管的異常處理是什麽?就是這些異常和正常的業務邏輯相關的那些異常:它們發生的時候,業務邏輯轉向了另外的一個正常處理分支.

7、Django Signals的一個應用場景,Django的Signals機制並不是異步消息機制,他基本接近裝飾器,是一種同步掛鉤模式,同步就限制了它的業務設計場景,但是在實現設計角度還是有用的:Python的import會有死鎖循環問題,Linux的執行環境比較嚴格,像字符串編碼和import循環的問題會比windows更容易發生,import循環這個問題,從設計的角度講就需要嚴格的架構分層設計,同層之間調用要盡量限制,跨層反向要絕對禁止,但是任何模塊調用是復雜的,不可能絕對滿足約束,singals的掛鉤機制,隔離le 調用方,應該可以解決跨層反向調用的Import問題.(此方案未經實際應用測試)

8、再談循環Import的架構層解決,在Django中跨App的Model依賴有可能比較平常,這種同層依賴甚至逆架構層方向的反向依賴都有可能導致import循環,對於逆架構層反向依賴這種現象應該是盡量避免,對於同層之間的數據依賴,應該盡量堅持view和所有的model屬於同一個app之內,那麽跨App依賴怎麽解決?1、前端異步依賴,可以在前端再加載依賴的數據,異步數據提供接口當然放在Model所在App內,2、模板標簽,正常的標簽肯定不會在其它py文件裏面被依賴,它正常情況下只被最頂端的模板代碼所依賴,這種情況下肯定不可能循環。3、model類之間的外鍵依賴循環,這個比較致命,不過解決辦法也很簡單,用字符串形式引用model會直接避免import,就沒有執行依賴了,不過這種方式要求必須把引用model所在的app加到settings的INSTALLED_APPS設置裏。

9、Django Session裏面如果放置列表此類的引用數據,在修改操作時,應該是賦值取出來,修改操作完,再賦值放回去,原處操作可能無效。後臺技術原因可能是因為Session串行化的原因

10、前端表單裏面沒有的model字段一定要在Form定義裏面Exclude掉,只在Model裏面定義blank和null只能做到驗證規則的定義,不能防止惡意用戶構造假表單填充這些model字段。後補:用fields meta信息定義要比exclude要好一點。

11、Django 代碼封裝的一個特殊優勢:當封裝代碼片段的操作對象是一個Model實例對象時,這個時候應該考慮借鑒Active Record的封裝設計,把這個代碼封裝成Model類的實例方法,這種封裝方式比Manager方法封裝要更Nice,應該說這是大多數業務邏輯可以優先考慮的封裝方式,起碼調用方式更Nice。

關於Django Web應用架構設計開發的幾個問題