Xử lý lệnh và DDD


10

Tôi có một ứng dụng ASP.NET MVC, sử dụng dịch vụ truy vấn để lấy dữ liệu và dịch vụ lệnh để gửi lệnh. Câu hỏi của tôi là về phần lệnh.

Nếu một yêu cầu đến, dịch vụ lệnh sử dụng một bộ điều phối lệnh sẽ định tuyến lệnh đến bộ xử lý lệnh được chỉ định của nó. Trình xử lý lệnh này xác nhận hợp lệ trước và nếu mọi thứ đều được chấp nhận, nó sẽ thực thi lệnh.

Ví dụ cụ thể: AddVerToArticleCommandHandler nhận được AddVerToArticleCommand, có một ArticleId, CommentText và EmailAddress.

Đầu tiên; xác thực phải xảy ra, như: - kiểm tra xem bài viết có tồn tại không - kiểm tra xem bài viết chưa bị đóng - kiểm tra xem văn bản bình luận có được điền vào và từ 20 đến 500 ký tự không - kiểm tra xem địa chỉ email có được điền không và có định dạng hợp lệ không.

Tôi đang tự hỏi nơi để xác nhận này?

1 / trong trình xử lý lệnh chính nó. Nhưng sau đó, nó không thể được sử dụng lại trong các trình xử lý lệnh khác.

2 / trong thực thể miền. Nhưng vì một thực thể miền không biết về kho lưu trữ hoặc dịch vụ, nó không thể thực hiện xác nhận cần thiết (không thể kiểm tra xem một bài viết có tồn tại hay không). Nhưng mặt khác, nếu thực thể không chứa logic, thì nó trở thành một thùng chứa dữ liệu đơn giản, không tuân theo các nguyên tắc DDD.

3 / trình xử lý lệnh sử dụng trình xác nhận, để xác thực có thể được sử dụng lại trong các trình xử lý lệnh khác.

4 / Cơ chế nào khác?

Tôi đang tìm kiếm chuỗi trách nhiệm cho ví dụ cụ thể này và những đối tượng (thực thể, kho lưu trữ, ...) đóng vai trò gì trong đó.

Bạn có ý tưởng về cách bạn sẽ thực hiện điều này, bắt đầu từ trình xử lý lệnh cho đến kho lưu trữ không?


"Nhưng là một thực thể miền không biết về kho lưu trữ hoặc dịch vụ, nó không thể thực hiện xác nhận cần thiết"? Tại sao không? Nguyên tắc nào của DDD yêu cầu điều này?
S.Lott

Tôi đọc ở khắp mọi nơi rằng một thực thể không nên biết về kho lưu trữ hoặc bất cứ điều gì khác.
L-Four

Bạn có thể cung cấp một trích dẫn, liên kết hoặc ví dụ về những gì - cụ thể - bạn đã đọc? Chúng tôi không biết mô tả về DDD bạn đang đọc.
S.Lott


Jimmy Bogard đã chia sẻ một số quan điểm về chủ đề này ... Lostechies.com/jimmybogard/2009/02/15/validation-in-a-ddd-world
Mayo

Câu trả lời:


4

Tôi nghĩ bạn cần tách hai loại xác nhận trong trường hợp này; xác nhận tên miềnxác nhận ứng dụng .

Xác thực ứng dụng là những gì bạn có khi xác minh rằng 'văn bản' thuộc tính lệnh có từ 20 đến 200 ký tự; vì vậy, bạn xác nhận điều này với GUI và với trình xác thực mô hình khung nhìn cũng thực thi tại máy chủ sau khi POST. Điều tương tự cũng xảy ra với e-mail (btw, tôi hy vọng bạn nhận ra rằng một e-mail như `32.d +" Hello World .42 "@ mindomän.local" là hợp lệ theo RFC).

Sau đó, bạn có một xác nhận khác; kiểm tra xem bài viết đó có tồn tại không - bạn phải tự hỏi mình câu hỏi tại sao bài viết không nên tồn tại nếu thực sự có một lệnh được gửi từ GUI về việc đính kèm một bình luận cho nó. GUI của bạn cuối cùng có nhất quán và bạn có một gốc tổng hợp, bài viết, có thể bị xóa khỏi kho lưu trữ dữ liệu không? Trong trường hợp đó, bạn chỉ cần di chuyển lệnh đến hàng đợi lỗi vì trình xử lý lệnh không tải được tổng hợp gốc.

Trong trường hợp trên, bạn sẽ có cơ sở hạ tầng xử lý các tin nhắn độc hại - ví dụ, họ sẽ thử lại tin nhắn 1-5 lần và sau đó di chuyển nó đến hàng đợi phân chia nơi bạn có thể kiểm tra thủ công bộ sưu tập tin nhắn và gửi lại những tin nhắn có liên quan. Đó là một điều tốt để theo dõi.

Vì vậy, bây giờ chúng tôi đã thảo luận:

  • Xác nhận ứng dụng

    • Với javascript trong GUI
    • Với xác thực MVC tại máy chủ web
  • Thiếu gốc tổng hợp + hàng đợi độc

Còn các lệnh không đồng bộ với miền thì sao? Có lẽ bạn có một quy tắc trong logic tên miền của mình khi nói rằng sau 5 bình luận cho một bài viết, chỉ cho phép bình luận dưới 400 ký tự, nhưng một anh chàng đã quá muộn với bình luận thứ 5 và trở thành người thứ 6 - GUI không nắm bắt được vì nó không phù hợp với tên miền tại thời điểm anh ta gửi lệnh của mình - trong trường hợp này bạn có 'lỗi xác thực' là một phần của logic miền của bạn và bạn sẽ trả về sự kiện lỗi tương ứng.

Sự kiện này có thể ở dạng tin nhắn lên một nhà môi giới tin nhắn hoặc người điều phối tùy chỉnh của bạn. Máy chủ web, nếu ứng dụng là nguyên khối, có thể lắng nghe đồng bộ cả sự kiện thành công và sự kiện thất bại được đề cập và hiển thị chế độ xem / bộ phận phù hợp.

Thường thì bạn có sự kiện tùy chỉnh có nghĩa là thất bại đối với nhiều loại lệnh và đó là sự kiện mà bạn đăng ký theo quan điểm của máy chủ web.

Trong hệ thống mà chúng tôi đang làm việc, chúng tôi đang thực hiện phản hồi yêu cầu với các lệnh / sự kiện qua một bus môi giới MassTransit + RabbitMQ và chúng tôi có một sự kiện trong miền cụ thể này (mô hình hóa một quy trình công việc) được đặt tên InvalidStateTransitionError. Hầu hết các lệnh cố gắng di chuyển dọc theo một cạnh trong biểu đồ trạng thái có thể gây ra sự kiện này. Trong trường hợp của chúng tôi, chúng tôi sẽ lập mô hình GUI theo mô hình nhất quán cuối cùng và vì vậy chúng tôi gửi người dùng đến trang 'được chấp nhận lệnh' và sau đó cho phép các chế độ xem của máy chủ web cập nhật thụ động thông qua đăng ký sự kiện. Cần phải đề cập rằng chúng tôi cũng đang thực hiện tìm nguồn cung ứng sự kiện trong các gốc tổng hợp (và cũng sẽ làm cho sagas).

Vì vậy, bạn thấy, rất nhiều xác nhận mà bạn đang nói đến thực sự là xác nhận kiểu ứng dụng, không phải logic miền thực tế. Không có vấn đề gì khi có một mô hình miền đơn giản nếu tên miền của bạn đơn giản nhưng bạn đang thực hiện DDD. Tuy nhiên, khi bạn tiếp tục mô hình hóa tên miền của mình, bạn sẽ phát hiện ra rằng tên miền có thể không đơn giản như lần đầu tiên xuất hiện. Trong nhiều trường hợp, gốc / thực thể tổng hợp có thể chỉ chấp nhận một lời gọi phương thức gây ra bởi một lệnh và thay đổi một số trạng thái của nó mà không thực hiện bất kỳ xác nhận nào - đặc biệt là nếu bạn tin tưởng các lệnh của mình như bạn làm nếu bạn xác thực chúng trong máy chủ web bạn kiểm soát.

Tôi có thể giới thiệu và xem hai bài thuyết trình về DDD từ Hội nghị nhà phát triển Na Uy 2011 và cả bài thuyết trình của Greg tại Öredev 2010 .

Chúc mừng, Henke


Cảm ơn! Một điều về xác thực: hiện tại, xác thực này được kích hoạt bởi giao diện người dùng (bằng cách đưa ra yêu cầu Xác thực (lệnh) cho dịch vụ), sử dụng Xác thực () của chính thực thể Nhận xét. Sau đó, nếu lệnh hợp lệ, máy khách sẽ phát lệnh Execute, lệnh này sẽ thực thi lại Xác thực () để đảm bảo và nếu hợp lệ thì lệnh thực tế được thực thi. Vì vậy, xác thực chính được thực hiện bởi thực thể Nhận xét, bởi vì trong mọi ngữ cảnh, xác thực sẽ giống nhau (email luôn phải hợp lệ, văn bản nhận xét không quá dài, v.v.) Đây có phải là một cách tiếp cận tốt?
L-Four

Việc xác thực mà bạn dường như đang mô tả dường như không đảm bảo cho tôi mô hình hóa nó bằng giao thức xác thực 2 pha - chắc chắn, xác thực các tham số của lời gọi phương thức trên thực thể như bạn đã kiểm tra trong một bài kiểm tra đơn vị, nhưng bên cạnh đó; lớp ứng dụng / GUI có thể dễ dàng xác nhận các quy tắc mà bạn đang mô tả mà không cần gửi lệnh đến miền. Imo Trừ khi máy khách là độc hại, lệnh sẽ hoạt động. Nếu máy khách là độc hại thì lệnh thất bại và mô hình đọc của bạn không bao giờ có một sự kiện tương ứng và bạn có thể kiểm tra lệnh có vấn đề trong hàng đợi lỗi.
Henrik

Trong UI (ASP.NET MVC) Tôi đang sử dụng các thuộc tính xác thực để thực hiện tất cả xác thực. Vì vậy, nếu xác thực này thành công, tôi không phải xác nhận lại trên miền, nhưng chỉ cần thực hiện lệnh?
L-Four

1
Có, bạn thực thi lệnh nhưng đảm bảo rằng lệnh không hợp lệ cả trong lớp ứng dụng và miền.
Henrik

0

EDIT: WaybackMachine link: http://devlicio.us/bloss/billy_mccafferty/archive/2009/02/17/a-response-to-validation-in-a-ddd-world.aspx

Không có câu trả lời.

Có hai kịch bản dự án rõ ràng xuất hiện trong đầu tôi khi tôi cố gắng trả lời nơi xác nhận nên sống. Đầu tiên là trong đó một lớp DTO được sử dụng để chuyển thông tin giữa lớp xem và lớp miền. Ví dụ: bạn có thể có một đối tượng Khách hàng trong lớp miền của mình và DTO của Khách hàng được liên kết trong một lớp khác mà bạn ánh xạ thông tin Khách hàng, sau đó đưa ra chế độ xem để trình bày thông tin Khách hàng cho người dùng.

Kịch bản thứ hai là một dự án trong đó các thực thể trong lớp miền được chia sẻ trực tiếp với khung nhìn để trình bày dữ liệu cho người dùng. Ví dụ: thay vì duy trì một lớp DTO riêng biệt và đối tượng miền ánh xạ tới các DTO được cung cấp cho chế độ xem, chế độ xem có thể được cung cấp trực tiếp cho đối tượng Khách hàng. Vì vậy, thay vì nói chuyện thông qua một DTO được duy trì riêng biệt để hiển thị tên của Khách hàng, chế độ xem chỉ đơn giản là hỏi chính đối tượng Khách hàng để biết thông tin.

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.