Nói đúng, một Kho lưu trữ cung cấp ngữ nghĩa bộ sưu tập để nhận/đưa các đối tượng miền. Nó cung cấp một trừu tượng xung quanh việc thực hiện hiện thực hóa của bạn (ORM, được cuộn tay, mô phỏng) để người tiêu dùng của các đối tượng miền được tách riêng khỏi các chi tiết đó. Trong thực tế, một Repository thường tóm tắt quyền truy cập vào các thực thể, tức là các đối tượng miền có nhận dạng và thường là vòng đời liên tục (trong DDD, một Repository cung cấp quyền truy cập vào các Roots tổng hợp).
Một giao diện tối thiểu cho một kho lưu trữ như sau:
void Add(T entity);
void Remove(T entity);
T GetById(object id);
IEnumerable<T> Find(Specification spec);
Mặc dù bạn sẽ thấy sự khác biệt đặt tên và việc bổ sung Save/SaveOrUpdate ngữ nghĩa, phía trên là ý tưởng 'tinh khiết'. Bạn nhận được các thành viên Add/Remove ICollection cộng với một số người tìm kiếm.Nếu bạn không sử dụng IQueryable, bạn cũng sẽ thấy các phương thức tìm kiếm trên kho lưu trữ như:
FindCustomersHavingOrders();
FindCustomersHavingPremiumStatus();
Có hai vấn đề liên quan đến việc sử dụng IQueryable trong ngữ cảnh này. Thứ nhất là tiềm năng rò rỉ chi tiết triển khai cho khách hàng dưới dạng mối quan hệ của đối tượng tên miền, tức là vi phạm Luật Demeter. Thứ hai là kho lưu trữ tìm kiếm các trách nhiệm có thể không thuộc về kho lưu trữ đối tượng miền thích hợp, ví dụ: tìm các phép chiếu ít về đối tượng miền được yêu cầu hơn so với dữ liệu có liên quan.
Ngoài ra, bằng cách sử dụng IQueryable 'ngắt' mẫu: Kho lưu trữ với IQueryable có thể hoặc không thể cung cấp quyền truy cập vào 'đối tượng miền'. IQueryable cung cấp cho khách hàng rất nhiều tùy chọn về những gì sẽ được thực hiện khi truy vấn cuối cùng được thực thi. Đây là lực đẩy chính của cuộc tranh luận về việc sử dụng IQueryable.
Về giá trị vô hướng, bạn không nên sử dụng kho lưu trữ để trả về giá trị vô hướng. Nếu bạn cần một vô hướng, bạn thường sẽ nhận được điều này từ chính thực thể đó. Nếu điều này nghe có vẻ không hiệu quả, có nghĩa là, nhưng bạn có thể không nhận thấy, tùy thuộc vào các đặc tính/yêu cầu tải của bạn. Trong trường hợp bạn cần các chế độ xem thay thế của đối tượng miền, vì lý do hiệu suất hoặc vì bạn cần hợp nhất dữ liệu từ nhiều đối tượng miền, bạn có hai tùy chọn.
1) Sử dụng kho lưu trữ của đối tượng để tìm các thực thể và dự án/bản đồ được chỉ định cho chế độ xem được làm phẳng.
2) Tạo giao diện công cụ tìm dành riêng để trả về loại tên miền mới đóng gói chế độ xem phẳng mà bạn cần. Đây sẽ không phải là một Kho lưu trữ vì sẽ không có ngữ nghĩa Bộ sưu tập, nhưng nó có thể sử dụng các kho lưu trữ hiện có dưới các bìa.
Một điều cần xem xét nếu bạn sử dụng Kho lưu trữ 'thuần' để truy cập các thực thể tồn tại là bạn thỏa hiệp một số lợi ích của ORM. Trong một triển khai 'thuần', khách hàng không thể cung cấp ngữ cảnh cho cách đối tượng miền sẽ được sử dụng, vì vậy bạn không thể nói kho lưu trữ: 'hey, tôi sẽ thay đổi thuộc tính customer.Name, do đó, don 't bận tâm nhận được những tài liệu tham khảo háo hức nạp.' Mặt khác, câu hỏi đặt ra là liệu một khách hàng có nên biết về những thứ đó không. Đó là một thanh kiếm hai lưỡi. Theo như sử dụng IQueryable, hầu hết mọi người dường như cảm thấy thoải mái với việc 'phá vỡ' mẫu để có được lợi ích của thành phần truy vấn động, đặc biệt là đối với các trách nhiệm của khách hàng như phân trang/phân loại. Trong trường hợp này, bạn có thể có:
Add(T entity);
Remove(T entity);
T GetById(object id);
IQueryable<T> Find();
và sau đó bạn có thể làm đi với tất cả các phương pháp đó Finder tùy chỉnh, mà thực sự lộn xộn Repository như yêu cầu truy vấn của bạn phát triển.
Tôi đã xem bài đăng của jbogard về chủ đề này hôm nay: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/09/02/ddd-repository-implementation-patterns.aspx – pfries
+1: ". .. hầu hết mọi người dường như cảm thấy thoải mái với việc 'phá vỡ' mẫu để có được lợi ích của thành phần truy vấn động ... " –