當前一般的業務系統都會涉及到資料的持久化操作,但資料的持久化介質由於很多原因,一般都會選擇關聯式資料庫。
資料的重要性大家肯定都知道,商務邏輯寫的再正確,品質再高,如果資料來源有問題的話,得到的結果一樣也是錯誤的。所以保證資料庫中資料的邏輯安全性在系統開發中是很重要的一個工作內容。
我們這裡所說的安全性主要是資料邏輯安全性,因為像型別安全,主鍵唯一等這些資料庫都可以為我們檢測,但邏輯安全,資料庫就無能為力了,可能就需要我們系統自身的邏輯來維護。
- 1. 領域模型自身可以判斷的邏輯。例如一個項目領域對象,其本身可以判斷名稱不可為空,啟動時間必須小於結束時間,負責單位不可為空等等。這些都是領域邏輯對象通過本身現有的資訊都可以作出判斷。
- 2. 領域模型必須通過自身包含的許多附屬資訊才能作出判斷。例如,每個項目都有一個年投資計劃,每個月投入的人力計劃。例如這個項目的啟動和結束時間分別是2008和2015年,2008年的投資計劃是100萬,並且2008年的年六個月的人力投資計劃都已經添加到了資料庫中。當使用者修改項目的基本資料的時候,使用者把項目起始時間修改城2010年,這種修改在邏輯上肯定不不允許的。但這種判斷確實是商務邏輯的判斷,因此判斷代碼肯定應該是寫在領域模型中的,但這種判斷確實需要比較全面的資料支援。所以這種方式就可以在更新資料的函數中,讀取需要的全部資訊,然後再調用領域模型裡面的方法進行驗證。
- 3. 最後一種就是只有資料庫能夠驗證的邏輯了。這些邏輯同樣也是商務邏輯,但這種商務邏輯並不是某個領域模型所能夠處理的,而且這種邏輯本身就和資料持久化有關。例如在添加使用者的時候要簡單當前系統資料庫中是不是已經存在該使用者名稱的使用者。這些都必須在持久層裡面判斷。還有一些判斷,雖然是應該屬於某個領域模型判斷,但要是把所有相關的資料都取出來,進行邏輯判斷,那麼代價就太高了,所以這種要需要在資料持久層裡面直接使用Sql語句進行操作。
總之,作為以上三種判斷類型的歸屬問題還是盡量把代碼寫在領域模型和領域邏輯裡面,如果某個邏輯判斷確實不屬於邏輯問題,可能就需要放置到資料持久化層,使用Sql語句直接判斷或是其他地方。
其實資料持久化層已經成為了記憶體對象和資料庫的映射層,通過這個層來擷取和儲存資料,並保持資料的安全性和穩定性。不論那些邏輯判斷的代碼寫在什麼地方,是領域模型裡面,還是持久化本身裡面,在執行資料庫操作的時候,都要進行全部的驗證,並且這些驗證的調用要原子話,就是在調用持久化層的某個Add函數時,資料持久化層已經給你做了全部的驗證,不用你提前做任何判斷。
我們也可以在UI上提前進行驗證,但這些驗證我們都稱作不安全的,例如,一個刪除類別的操作,介面顯示,在此列別下面已經沒有任何子類別,因為使用者從介面顯示,到看的過程,以及執行操作(如果他開啟後,去了趟廁所,可能時間會更長)這將持續很長的時間,所以在這段時間內,你不可能保證別人沒有在此類型下面添加新的子類型,所以如果在持久化的刪除函數中沒有做任何判斷,就可能導致錯誤的操作邏輯。