Nơi để xác nhận các quy tắc mô hình miền phụ thuộc vào nội dung cơ sở dữ liệu?


10

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ớpxác thực nhập dữ liệu - Ở đâu? Bao nhiêu? .


Tạo mô hình hoạt động tuyệt vời với tất cả các xác nhận. Nhưng khi bạn muốn chỉnh sửa hoặc xem biểu mẫu, xác thực cũng bắt đầu. Điều này ném ngoại lệ cho các trường trống hoặc có giá trị không hợp lệ - có thể đã thay đổi trong db hoặc được tải từ Excel. Giải pháp dự kiến ​​là cho phép biểu mẫu hiển thị khi cập nhật để Quản trị viên có thể sửa các trường đó.
tunmise fasipe 10/07/2015

Câu trả lời:


4

Làm thế nào phức tạp là các xác nhận? Thông thường các xác nhận yêu cầu kết hợp các trường và hoặc quy tắc kinh doanh dựa trên các trường để được đánh giá chính xác.

Các xác nhận càng phức tạp, tùy chọn # 2 càng khó và ít hiệu suất.

Tất nhiên, tầng dữ liệu có thể gọi dịch vụ xác nhận vào thời gian liên tục. Điều này có thể giúp tình huống kỳ lạ khi dữ liệu ở trạng thái không hợp lệ do thay đổi quy tắc.

Mục khác đáng để nhận xét là khả năng thay đổi quy tắc xác thực mà không có chu kỳ qa nào đó. Nhưng đó là một chủ đề cho một chủ đề khác nhau.

Với các thông tin trên, tùy chọn 1 có vẻ linh hoạt nhất giả sử bạn duy trì kỷ luật, tách biệt xác nhận và kiên trì.


0

Có thể bạn đang thiếu một lớp. Nếu không biết chi tiết về ứng dụng của bạn (yêu cầu, kiến ​​trúc, v.v.) tôi sẽ làm một cái gì đó giống như Client (dù đó là gì) -> Dịch vụ ứng dụng -> Mô hình miền

Lớp dịch vụ ứng dụng được phép tương tác với kho lưu trữ và mô hình miền chứa logic nghiệp vụ. Vì vậy, bạn có thể có một cái gì đó như:

FieldUpdateService >> updateField(fieldId, newValue)
  List<FieldRule> rules = this.rulesRepository.findRulesFor(fieldId)
  Field field = this.fieldRepository.find(fieldId)
  try 
    field.updateValue(rules,newValue)
    fieldRepository.save(field)
  catch 
    // manage error

Nếu bạn có mối quan hệ với một Trường và FieldRules của anh ấy và sử dụng ORM như Hibernate trong Java, bạn sẽ chỉ làm:

FieldUpdateService >> updateField(fieldId, newValue)
  Field field = this.fieldRepository.find(fieldId)
  try 
    field.updateValue(newValue)
    fieldRepository.save(field)
  catch 
    // manage error

Field >> updateValue(newValue)
  for rule in rules
     if !rule.isValid(newValue)
        throw ValueNotAllowedException
  this.value = newvalue

Bởi vì truy vấn ORM và khởi tạo đồ thị của các đối tượng mà bạn yêu cầu.

Liên quan đến nghi ngờ của bạn về thực tế rằng ai đó có thể làm

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

Ai đó cũng có thể viết: FieldRule alwaysReturnTrueRule = new FieldRule {isValid (newValue) {return true; }} field.updateValue ("uncheckedValue", alwaysReturnTrueRule) Đó là một ví dụ khó hiểu nhưng điều tôi nói là không có gì bảo vệ bạn khỏi việc sử dụng mã xấu. Có lẽ tài liệu tốt và hài hước mặt đối mặt. Tôi nghĩ rằng không có gì bảo vệ bạn khỏi việc sử dụng mã xấu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.