使用休眠的一個挑戰是,管理類必須具有默認構造函數。問題在於,沒有明確指出類的初始化位置,並且可以檢查不變量。檢查休眠映射類中的不變量
如果一個類具有依賴於多個屬性的不變式,則類設計變得複雜。讓我們開始與假設綠色領域的設計:
public class A {
private int x;
private int y;
public A(int x, int y) {
this.x = x;
this.y = y;
checkInvariants(this.x, this.y);
}
private void checkInvariants(int x, int y) {
if (x + y « 0) throw new IllegalArgumentException();
}
}
這是基本實現不符合休眠要求。在構造函數中檢查不變量。 (該checkInvariants的內容()方法不要緊它只是以說明的是,類不變量可以依賴於一個以上的財產。)
的類可以使用如下:
new A(0, 0);
new A(-1, 0); //invalid
要滿足休眠要求一個解決方法是添加一個私人默認構造函數和使用字段訪問。 (我省略了休眠映射)。
public class H {
int x;
int y;
public H(int x, int y) {
this.x = x;
this.y = y;
checkInvariants(this.x, this.y);
}
H(){}
private void checkInvariants(int x, int y) {
if (x + y « 0) throw new IllegalArgumentException();
}
}
這有兩大缺點: *你開始執行代碼取決於客戶(休眠)上。理想情況下,一個班級不知道其來電者。 *此變通辦法的一個具體問題是,由休眠啓動的實例是未檢查是否符合不變量。你信任從數據庫加載的數據是有問題的。即使您的應用程序是唯一使用此特定數據庫架構的應用程序,管理員也可能會隨時進行臨時更改。
的第二解決方法是在用戶代碼檢查不變量:
顯然,這使得用戶代碼更復雜和容易出錯。這種設計不符合創建後實例一致的期望,並且在每次更改狀態(方法調用)後都保持一致。每個用戶都必須檢查他創建的每個實例的不變量(可能間接使用休眠)。
是否有更好的解決這個問題,就是:
- 沒有過於複雜的
- 沒有關於其用戶
- 顯性知識,而不依賴於Hibernate框架?
我想一些約束必須放鬆才能得到實用的解決方案。唯一的硬約束是對hibernate框架沒有依賴性。 (域對象之外的Hibernate特定代碼是可以的)。
(只是出於好奇:有沒有支持「構造函數注入」的ORM框架?)
這種規則應該由數據庫中的檢查約束,這將避免加載情況下違反該規則執行。 – araqnid 2009-10-26 18:05:20
這個問題沒有成效。您試圖將永久約束強制的「任意哲學」強加到可變數據上 - 根據定義,這種數據在單個原子更新中不可更新。你不是在試圖解決一個有效的商業或設計問題,只是把BS推到臺車上。 – 2013-04-06 00:33:45
@ThomasW每個人每時每刻都有糟糕的一天。乾杯! (也許它可以幫助你發現什麼是不變量。) – 2013-04-11 18:49:48