Tôi đang làm việc trên một hệ thống cho phép Quản trị viên xác định Biểu mẫu có chứa Trường. Các biểu mẫu được xác định sau đó được sử dụng để nhập dữ liệu vào hệ thống. Đôi khi các Biểu mẫu được điền bởi một người thông qua GUI, đôi khi Biểu mẫu được điền dựa trên các giá trị được báo cáo bởi một hệ thống khác.
Đối với mỗi Trường, Quản trị viên có thể xác định Quy tắc xác thực giới hạn các giá trị được phép cho Trường. Quy tắc xác thực có thể là bất cứ điều gì từ "giá trị được nhập trong Trường phải là Đúng hoặc Sai" đến "giá trị được nhập trong Trường phải tồn tại trong cột A của bảng B trong cơ sở dữ liệu". Quản trị viên bất cứ lúc nào cũng có thể thay đổi Quy tắc xác thực cho Trường.
Trong kịch bản này, theo bạn, đâu là nơi phù hợp nhất để xác thực rằng mỗi Trường được điền chính xác? Tôi hiện có hai cách tiếp cận chính trong tâm trí:
Tùy chọn # 1: Xác thực trong Mô hình miền
Mỗi đối tượng Trường sẽ chứa Quy tắc xác thực được chỉ định bởi Quản trị viên. Các đối tượng Trường cũng sẽ có một tham chiếu đến IValidator. Khi một nỗ lực được thực hiện để đặt giá trị của Trường, Trường sẽ chuyển giá trị đã cho và Quy tắc xác thực cho IValidator. Nếu giá trị đã cho không hợp lệ, thì ExceptionException sẽ được ném và xử lý thích hợp trong GUI / giao diện cho hệ thống khác.
Ưu điểm:
- Bảo vệ mạnh mẽ đối với các trường vô tình được gán các giá trị vi phạm Quy tắc xác thực
Nhược điểm:
Lớp truy cập dữ liệu cần có khả năng bỏ qua xác thực và xây dựng các trường vi phạm Quy tắc xác thực hiện tại. Mặc dù Quản trị viên thay đổi Quy tắc xác thực cho một trường, chúng ta vẫn cần có thể xây dựng các đối tượng Trường dựa trên dữ liệu cũ, ví dụ như khi hiển thị Biểu mẫu đã được điền từ nhiều năm trước. Điều này có khả năng có thể được giải quyết bằng cách lưu trữ Quy tắc xác thực hiện tại bất cứ khi nào chúng tôi lưu trữ Trường.
Trong thiết kế này, mô hình Trường có một liên kết gián tiếp đến Lớp / Kho lưu trữ dữ liệu thông qua IValidator. Việc tiêm Dịch vụ / Kho lưu trữ vào Mô hình miền dường như thường được tán thành .
Tùy chọn # 2: Xác thực trong một dịch vụ
Cố gắng đảm bảo rằng tất cả các nỗ lực để đặt giá trị của Trường đi qua Dịch vụ đảm bảo Quy tắc xác thực được giữ. Nếu Quy tắc xác thực bị vi phạm, hãy ném Xác thực ngoại lệ.
Tất nhiên, Lớp truy cập dữ liệu sẽ không sử dụng Dịch vụ khi tạo các đối tượng Trường đã được duy trì trước đó trong DB.
Ưu điểm:
Không vi phạm "không tiêm Dịch vụ / Kho lưu trữ vào Mô hình miền của bạn" -thinking.
Không cần phải duy trì Quy tắc xác thực hiện tại khi duy trì Trường. Dịch vụ có thể chỉ cần tra cứu Quy tắc xác thực hiện tại cho Trường; khi xem dữ liệu lịch sử, giá trị của Trường sẽ không bị thay đổi.
Nhược điểm:
- Không đảm bảo rằng tất cả logic nên sử dụng Dịch vụ để đặt giá trị Trường thực sự làm như vậy. Tôi thấy đây là một nhược điểm lớn; tất cả dường như chỉ cần ai đó viết "thisField.setValue (thatField.getValue ())" và Quy tắc xác thực của thisField này có thể bị vi phạm mà không ai là người khôn ngoan hơn. Điều này có khả năng có thể được giảm thiểu bằng cách đảm bảo rằng giá trị của Trường khớp với Quy tắc xác thực khi Lớp truy cập dữ liệu sắp duy trì Trường.
Hiện tại tôi thích Tùy chọn # 1 hơn Tùy chọn # 2, chủ yếu vì tôi thấy đây là logic kinh doanh và cảm thấy Tùy chọn # 2 có nguy cơ cao hơn trong việc giới thiệu dữ liệu xấu cho hệ thống. Tùy chọn nào bạn thích, hoặc có một thiết kế khác phù hợp với kịch bản này tốt hơn hai tùy chọn được mô tả?
Chỉnh sửa (Độ phức tạp của xác nhận)
Các trường hợp xác nhận đã được đưa ra cho đến nay là tương đối đơn giản; giá trị Trường phải là số, ví dụ: ngày, ngày có thời gian hoặc là giá trị hiện có trong cột cơ sở dữ liệu. Tuy nhiên, tôi nghi ngờ sự phức tạp sẽ tăng dần theo thời gian. Ví dụ: giải pháp xác thực cần được xây dựng với mục đích quốc tế hóa - những thứ như Ngày có thể được nhập theo cú pháp cụ thể của miền địa phương.
Bây giờ tôi đã quyết định tiến hành Tùy chọn # 1, cố gắng hết sức để không gán quá nhiều trách nhiệm cho Mô hình Miền. Những người phải đối mặt với một tình huống tương tự cũng có thể muốn kiểm tra các câu hỏi liên quan Xác thực và ủy quyền trong kiến trúc phân lớp và xác thực nhập dữ liệu - Ở đâu? Bao nhiêu? .