Cách xử lý các lệnh Thêm / Tạo * trong kiến ​​trúc Tìm nguồn sự kiện CQRS +


11

Tôi muốn triển khai ứng dụng đầu tiên của mình bằng cách sử dụng mẫu CQRS cùng với Tìm kiếm sự kiện. Tôi đang tự hỏi làm thế nào để tạo ra rễ tổng hợp nên được xử lý đúng. Giả sử ai đó gửi lệnh CreatItem. Làm thế nào nó nên được xử lý? Nơi lưu trữ sự kiện ItemCreated? Là sự kiện đầu tiên của một mặt hàng mới? Hoặc tôi nên có một số loại thực thể ItemList tổng hợp tất cả các mục và danh sách sự kiện của nó chỉ bao gồm các sự kiện ItemCreated?

Udi Dahan đề nghị không tạo ra các gốc tổng hợp và luôn luôn sử dụng thay vào đó một số phương pháp tìm nạp. Nhưng làm thế nào tôi có thể tìm nạp một cái gì đó mới và chắc chắn không có bất kỳ ID nào được chỉ định. Tôi hiểu ý tưởng đằng sau và khá hợp lý khi nghĩ rằng một đối tượng mới là một đối tượng có trạng thái bao gồm các sự kiện bằng không trả lời về nó. Nhưng tôi nên sử dụng nó như thế nào? Tôi nên có một phương thức riêng biệt trong Kho lưu trữ của mình như thế nào getNewItem()hoặc thay vào đó làm cho get(id)phương thức của tôi chấp nhận Optional<ItemId>?

Chỉnh sửa: Sau một thời gian đào tôi thấy việc triển khai thực sự thú vị các mẫu đã nói ở trên bằng cách sử dụng các diễn viên. Tác giả thay vì tạo tập hợp, lấy nó từ một loại kho lưu trữ với UUID mới được tạo. Hạn chế của phương pháp này là ông cho phép trạng thái không nhất quán tạm thời. Tôi cũng tự hỏi làm thế nào tôi có thể thực hiện deletephương pháp với cách tiếp cận như vậy. Đơn giản chỉ cần thêm sự kiện đã xóa vào danh sách sự kiện của tổng hợp?


1
Tôi nghi ngờ tiêu đề bài viết của Udi là sai lệch. IMHO nghe có vẻ như mục tiêu thực sự của anh ấy là các AR mới được tạo ra phải luôn có thể truy cập được từ một nơi khác, theo cách nắm bắt bối cảnh về lý do tại sao / làm thế nào / ai quyết định rằng AR mới cần được tạo ra. Mọi thứ khác là về cách một triển khai cụ thể (NHibernate?) Có thể giúp quản lý dễ dàng hơn.
Darien

2
Lưu ý rằng bài viết của Udi Dahan mà bạn tham khảo đặc biệt gọi rằng lời khuyên của anh ấy có thể không áp dụng cho tìm nguồn cung ứng sự kiện: udidahan.com/2009/06/29/dont-create-aggregate-roots/ trộm
EZ Hart

Câu trả lời:


13

Ý tưởng trong bài viết của Udi, khi tôi tập hợp, là không có loại vật phẩm nào xuất hiện trong không khí mỏng. Luôn luôn có một cái gì đó, hoặc cụ thể hơn là một số hoạt động tên miền, khiến cho mục được tạo. Giống như ví dụ của Udi về một người dùng thực sự được sinh ra từ một khách truy cập đăng ký vào trang web. Tại thời điểm đó và tại bối cảnh giới hạn đó, Khách truy cập là gốc tổng hợp, được truy xuất bằng địa chỉ IP của anh ta. Khách truy cập này sau đó tạo ra "mục" mới, một người dùng tại thời điểm này, thông qua một hoạt động tên miền được gọi là Đăng ký . Tương tự với bước trước, đó là một bối cảnh bị ràng buộc khác: Giới thiệu là AR, được lấy ra bởi URL và có một hoạt động tên miền được gọi là BvedVisitorWithIp , nơi khách truy cập được sinh ra.

Udi cũng viết rất hay về việc xóa: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/ . Ý tưởng chính là, bạn không xóa bất cứ điều gì, bao giờ. Luôn có một hoạt động tên miền phía sau, mà chúng tôi muốn nắm bắt. Giống như một đơn đặt hàng bị hủy, thay vì bị xóa. Đọc nó, nó là một bài viết rất tốt.

Điểm chính ở đây trên cả hai tài khoản, thực hiện DDD và đặc biệt là Tìm kiếm sự kiện, là bạn không bao giờ nên thực hiện các thao tác CRUD thẳng. Nếu bạn thấy mình trong một tình huống mà bạn thực sự cần phải chèn, cập nhật hoặc xóa một số dữ liệu và thực sự không có hoạt động miền nào đằng sau nó, thì có lẽ DDD và Tìm nguồn sự kiện không phù hợp với bối cảnh bị ràng buộc đó . Bạn có thể tự do kết hợp hai điều này theo ý muốn miễn là một bối cảnh giới hạn duy nhất tuân thủ một nguyên tắc. Bằng cách này, bối cảnh giới hạn theo kiểu CRUD có thể tạo ra một số hàng trong cơ sở dữ liệu, trở thành một thực thể và gốc Tổng hợp trong một bối cảnh bị ràng buộc khác, nơi bạn có thể truy xuất AR và không phải tạo ra nó.


2
"có lẽ DDD và Tìm nguồn cung ứng sự kiện không phù hợp với bối cảnh bị ràng buộc đó." Bạn nhận được điểm của DDD ngay. Nó không nên được thực hiện trong mọi trường hợp chỉ vì vinh quang của satan mà chỉ khi người ta cần phải đối phó với một miền phức tạp chứa đầy các quy tắc không chắc chắn. Cá nhân tôi đã làm nó cho phần mềm pháp lý, nơi các yêu cầu không được điều khiển bởi logic.
Yegor Chumakov

2
+1 cho câu này một mình "cho bối cảnh bị ràng buộc đó." :)
Songo

2
+1 việc sử dụng các động từ 'Thêm' và 'Tạo' được khuyến nghị mạnh mẽ rằng bạn vẫn đang suy nghĩ về tên miền của mình về mặt tương tác với cơ sở dữ liệu dạng bảng cũ. Không biết tên miền / bối cảnh giới hạn của bạn, tôi không thể nói liệu điều này có phù hợp hay không. Bỏ qua sự kiên trì, trước tiên, hãy tập trung vào LỰA CHỌN và SỰ KIỆN (hay còn gọi là Ý TƯỞNG và NGOÀI RA) duy nhất cho miền của bạn, sau đó lo lắng về cách duy trì trạng thái, đây là vấn đề đã được giải quyết hàng trăm ngàn lần trước đây.
Matt

"Việc sử dụng các động từ 'Thêm' và 'Tạo' rất có ý nghĩa rằng bạn vẫn đang suy nghĩ về tên miền của mình về mặt tương tác với cơ sở dữ liệu dạng bảng cũ tốt" Hmmm. Khi bạn có một thiết kế UI có nút 'Thêm một cái gì đó lớn trong đó, thì thật đáng buồn, đó là ý định; nghĩa đen để thêm một cái gì đó mới. Tôi thường đồng ý với bạn, nhưng chúng tôi không nói về cấp độ cơ sở dữ liệu ở đây, đôi khi Thêm hoặc Tạo thực sự là những từ thích hợp để sử dụng.
designermonkey

1
@designermonkey Khi bạn có các nút đó trong UI, bạn có thực sự có một hoạt động tên miền đằng sau chúng không? Có lẽ, nhưng 9 trên 10 lần thực sự không cần một hoạt động tên miền phức tạp trong bối cảnh bị ràng buộc đó. Và hoạt động CRUD thuần túy chỉ là hoạt động CRUD thuần túy và nên được xử lý như vậy. Chỉ khi có nhu cầu về độ phức tạp của mô hình miền, thì nó mới được sử dụng. Do đó các bối cảnh giới hạn khác nhau với các nguyên tắc thiết kế khác nhau.
Tuukka Haapaniemi
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.