Một thử thách khi sử dụng ngủ đông là các lớp được mang phải có một hàm tạo mặc định . Vấn đề là không có điểm rõ ràng nơi lớp được khởi tạo và bất biến có thể được kiểm tra.Kiểm tra các bất biến trong các lớp được ánh xạ hibernate
Nếu một lớp có bất biến phụ thuộc vào nhiều hơn một thuộc tính thì thiết kế lớp sẽ trở nên phức tạp. Hãy bắt đầu với thiết kế trường xanh giả định:
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();
}
}
Đây là cơ sở triển khai không đáp ứng các yêu cầu ngủ đông. Bất biến được kiểm tra trong hàm tạo. (Phương pháp Nội dung của checkInvariants() không quan trọng nó chỉ được trình bày để minh họa rằng bất biến lớp có thể phụ thuộc vào nhiều hơn một thuộc tính.)
Lớp có thể được sử dụng như sau:
new A(0, 0);
new A(-1, 0); //invalid
Để đáp ứng các yêu cầu hibernate một workaround là thêm một private constructor mặc định và sử dụng truy nhập trường. (Tôi bỏ qua ánh xạ hibernate.)
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();
}
}
này có hai nhược điểm chính: * Bạn đang bắt đầu triển khai mã mà phụ thuộc vào khách hàng (Hibernate). Lý tưởng nhất, một lớp không biết người gọi của nó. * Một vấn đề cụ thể với cách giải quyết này là các trường hợp bắt đầu bằng ngủ đông là chưa được kiểm tra nếu đáp ứng các bất biến. Bạn đang tin tưởng dữ liệu được tải từ cơ sở dữ liệu có vấn đề. Ngay cả khi ứng dụng của bạn là người duy nhất sử dụng lược đồ cơ sở dữ liệu cụ thể này, luôn có khả năng các thay đổi đặc biệt của các quản trị viên.
Một cách giải quyết thứ hai là để bất biến kiểm tra trong người dùng mã:
Rõ ràng, điều này làm cho các mã sử dụng phức tạp hơn và dễ bị lỗi. Thiết kế này không đáp ứng được kỳ vọng rằng một cá thể nhất quán sau khi tạo và duy trì sự nhất quán sau mỗi lần thay đổi trạng thái (gọi phương thức). Mỗi người dùng phải kiểm tra các bất biến cho mỗi cá thể mà anh ta tạo ra (có thể gián tiếp với hibernate).
Có một giải pháp tốt hơn cho vấn đề này đó là:
- không quá phức tạp
- mà bạn không biết rõ ràng về người sử dụng
- mà không có một sự phụ thuộc vào khuôn khổ ngủ đông?
Tôi cho rằng một số ràng buộc phải được nới lỏng để có được giải pháp thực dụng. Khó khăn duy nhất là không có sự phụ thuộc vào khung công tác ngủ đông. (Hibernate mã cụ thể bên ngoài các đối tượng miền là okay).
(Ngừng tò mò: có khung ORM hỗ trợ “công cụ tiêm xây dựng” không?)
Loại quy tắc này nên được thực thi bởi ràng buộc kiểm tra trong cơ sở dữ liệu, điều này sẽ tránh được các trường hợp được tải trái với quy tắc. – araqnid
Câu hỏi không hiệu quả. Bạn đang cố gắng áp đặt một 'triết lý tùy ý' của việc thực thi ràng buộc vĩnh viễn, vào dữ liệu có thể thay đổi theo định nghĩa - không thể cập nhật trong một bản cập nhật nguyên tử duy nhất. Bạn không cố gắng giải quyết một vấn đề kinh doanh hoặc thiết kế hợp lệ, chỉ cần đẩy BS vào một xe đẩy. –
@ThomasW Mọi người đều có một ngày tồi tệ mọi lúc rồi. Chúc mừng! (Có lẽ nó có thể giúp nếu bạn tìm ra một bất biến là gì.) –