24

Tôi có câu hỏi liên quan đến DDD và mẫu kho lưu trữ.DDD - Cách triển khai kho lưu trữ hiệu năng cao để tìm kiếm

Giả sử tôi có kho lưu trữ Khách hàng cho thư mục gốc tổng hợp của Khách hàng. Phương thức Get & Tìm các phương thức trả về tập hợp đầy đủ, bao gồm các đối tượng như Địa chỉ, vv Tất cả đều tốt. Nhưng khi người dùng đang tìm kiếm một khách hàng trong giao diện người dùng, tôi chỉ cần một 'tóm tắt' của tổng hợp - chỉ là một đối tượng phẳng với thông tin tóm tắt. Một cách tôi có thể đối phó với điều này là gọi phương thức tìm kiếm trên kho như bình thường, và sau đó trong lớp ứng dụng, ánh xạ từng khách hàng tổng hợp vào CustomerSearchResult/CustomerInfo DTO và gửi lại cho khách hàng.

Nhưng vấn đề của tôi với điều này là hiệu suất; mỗi Tổng hợp khách hàng có thể yêu cầu nhiều truy vấn để điền tất cả các liên kết. Vì vậy, nếu tiêu chí tìm kiếm của tôi phù hợp với 50 khách hàng, đó là một cú đánh trên DB cho khả năng truy xuất dữ liệu mà tôi thậm chí không cần.

Vấn đề khác là tôi có thể bao gồm dữ liệu tóm tắt về khách hàng nằm ngoài ranh giới tổng thể của khách hàng, chẳng hạn như ngày của đơn đặt hàng cuối cùng được thực hiện chẳng hạn. Đơn đặt hàng có tổng hợp của riêng nó và do đó để có được thông tin đặt hàng của khách hàng, tôi sẽ phải gọi OrderRepository, cũng làm giảm hiệu suất.

Vì vậy, bây giờ tôi nghĩ tôi là trái với hai lựa chọn:

  1. Thêm một phương pháp Find bổ sung cho CustomerRepository mà trả về một danh sách các đối tượng này tóm tắt bằng cách thực hiện một truy vấn hiệu quả.

  2. Tạo một mục đích xây dựng readonly CustomerInfoRepository, mà chỉ có các phương pháp tìm được mô tả trong 1.

Nhưng cả hai cảm thấy như tôi đang đi ngược lại các nguyên tắc của DDD. Các kho lưu trữ của tôi kế thừa từ một cơ sở chung: Kho lưu trữ nơi T: IAggregateRoot. Các đối tượng thông tin tóm tắt này không phải là một tập hợp, và có một kiểu khác với T, vì vậy thực sự # 1 đi ngược lại thiết kế.

Có lẽ đối với # 2 tôi sẽ tạo một SearchRepository trừu tượng mà không có ràng buộc IAggregateRoot?

Có nhiều trường hợp tương tự trong miền của tôi.

Bạn sẽ triển khai kịch bản này như thế nào?

Cảm ơn, Dave

Cập nhật

Sau khi đọc câu trả lời Theo, tôi nghĩ rằng tôi sẽ đi với tùy chọn # 2 và tạo ra một SearchRepository chuyên ngành trong phạm vi cơ sở hạ tầng của tôi hướng tới những kịch bản. Tầng ứng dụng (các dịch vụ WCF) sau đó có thể gọi các kho lưu trữ này chỉ điền các DTO tóm tắt trực tiếp thay vì ánh xạ các thực thể miền tới các DTO.

**** Cập nhật 2 ****

Mặc dù tôi hỏi này hơn một năm trước, tôi nghĩ rằng tôi chỉ muốn thêm rằng tôi đã từ CQRS phát hiện đó là nhằm mục đích giải quyết vấn đề này chính xác.Udi Dahan (http://www.udidahan.com/) và Greg Young (http://codebetter.com/gregyoung/) đã viết rất nhiều về nó. Nếu bạn đang tạo một ứng dụng phân tán với DDD, CQRS là dành cho bạn!

Trả lời

24

Tôi nghĩ rằng bạn chỉ muốn hiển thị thông tin tóm tắt. Các bit của thông tin tóm tắt này không có các thực thể hoặc các đối tượng giá trị của mô hình miền. Họ chỉ là thông tin, không có gì hơn.

Nó giống như hiển thị thông tin báo cáo. Nếu tôi đối phó với những thứ như vậy, tôi sẽ không dính vào cách tiếp cận DDD thuần túy. Các tùy chọn được đề xuất của bạn là OK, bởi vì nó hoàn thành công việc của bạn. DDD không nên được coi là giáo điều. Suy nghĩ vượt khuôn khổ. Nới lỏng một chút DDD.

Nhưng lưu ý rằng bạn chỉ đang tạo các giá trị thông tin bên ngoài mô hình để hiển thị mục đích. Vì vậy, nếu người dùng chọn một bit thông tin để thực hiện một số thao tác với nó (được định nghĩa trong mô hình miền), bạn cần trích xuất mã định danh từ các giá trị thông tin và rút ra đối tượng/giá trị thực thể/tổng hợp từ một kho lưu trữ.

Tôi đề xuất video này: Eric Evans: What I've learned about DDD since the book. Nếu bạn đọc cuốn sách của mình, bạn thực sự sẽ thấy toàn bộ video. Chú ý rất gần vào khoảng thời gian 30:00, nơi Eric Evans tự nói về cốt liệu và đề cập đến vấn đề bạn đang gặp phải.

+0

Bạn nói đúng, chúng không phải là thực thể hoặc đối tượng giá trị. Tôi đoán thực sự những gì tôi đã hỏi là, các đối tượng tóm tắt này sẽ phù hợp với tên miền ở đâu? Tôi nghĩ câu trả lời là: họ không biết. Như bạn nói, chúng chỉ dành cho mục đích thông tin - tương tự như hiển thị thông tin báo cáo; họ đóng gói không có quy tắc kinh doanh. Đó là một video thú vị bằng cách này - tôi ngạc nhiên không gặp phải nó trước đây :) Cảm ơn, Dave –

+0

Câu trả lời hay. Tôi đang đối mặt với chính xác cùng một vấn đề và câu trả lời của bạn đã rất khai sáng. –

+0

Đây là câu hỏi SO có liên quan. Một số liên kết trong câu trả lời của Mohamed Abed rất hữu ích. http://stackoverflow.com/questions/7365913/how-do-read-only-database-views-fit-into-the-repository-pattern?lq=1 –

1

tôi sẽ:

  1. Return một đối tượng khác nhau đại diện cho một cái nhìn của đối tượng của tôi để trưng bày, ví dụ Thông tin khách hàng.
  2. Trả lại một DataTable. Thường thì một container chung là cách dễ nhất và tốt nhất để đi.

Nếu T trong kho lưu trữ cơ sở chung của bạn là Khách hàng, thì tôi nghĩ bạn đang áp dụng sai khái niệm về tổng hợp, mặc dù tôi không phải là nghiêm ngặt Evansangelist. Tôi sẽ thiết kế một kho lưu trữ cho Khách hàng trả về bất kỳ dữ liệu nào hợp lý hoặc thoải mái nhóm với Khách hàng, bao gồm cả DataTables hoặc các đối tượng chỉ đọc là các chế độ xem dữ liệu Khách hàng.