Dạng kho lưu trữ so với DAL


93

Họ là những điều tương tự? Vừa mới xem xong hướng dẫn về Mặt tiền cửa hàng của Rob Connery và chúng có vẻ giống nhau. Ý tôi là, khi tôi triển khai một đối tượng DAL, tôi có các phương thức GetStuff, Add / Delete, v.v. và tôi luôn viết giao diện trước để có thể chuyển đổi db sau.

Tôi có đang nhầm lẫn mọi thứ không?

Câu trả lời:


88

Bạn chắc chắn không phải là người nhầm lẫn mọi thứ. :-)

Tôi nghĩ câu trả lời cho câu hỏi phụ thuộc vào mức độ bạn muốn trở thành một người theo chủ nghĩa thuần khiết.

Nếu bạn muốn có một quan điểm DDD nghiêm ngặt, điều đó sẽ đưa bạn đi theo một con đường. Nếu bạn xem kho lưu trữ như một khuôn mẫu đã giúp chúng tôi chuẩn hóa giao diện của lớp ngăn cách giữa các dịch vụ và cơ sở dữ liệu, nó sẽ đưa bạn xuống một lớp khác.

Theo quan điểm của tôi, kho lưu trữ chỉ là một lớp truy cập dữ liệu được chỉ định rõ ràng, hay nói cách khác là một cách tiêu chuẩn hóa để triển khai Lớp truy cập dữ liệu của bạn. Có một số khác biệt giữa các triển khai kho lưu trữ khác nhau, nhưng khái niệm thì giống nhau.

Một số người sẽ đặt nhiều ràng buộc DDD hơn vào kho lưu trữ trong khi những người khác sẽ sử dụng kho lưu trữ như một trung gian thuận tiện giữa cơ sở dữ liệu và lớp dịch vụ. Một kho lưu trữ như DAL cô lập lớp dịch vụ khỏi các chi tiết cụ thể về truy cập dữ liệu.

Một vấn đề triển khai dường như làm cho chúng khác nhau, đó là một kho lưu trữ thường được tạo với các phương thức có đặc điểm kỹ thuật. Kho lưu trữ sẽ trả về dữ liệu thỏa mãn đặc điểm kỹ thuật đó. Hầu hết các DAL truyền thống mà tôi đã thấy, sẽ có một tập hợp các phương thức lớn hơn, nơi phương thức sẽ nhận bất kỳ số lượng tham số nào. Mặc dù điều này nghe có vẻ là một sự khác biệt nhỏ, nhưng đó là một vấn đề lớn khi bạn bước vào lĩnh vực Linq và Expressions. Giao diện kho lưu trữ mặc định của chúng tôi trông như thế này:

public interface IRepository : IDisposable
{
    T[] GetAll<T>();
    T[] GetAll<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter);
    T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
    void Delete<T>(T entity);
    void Add<T>(T entity);
    int SaveChanges();
    DbTransaction BeginTransaction();
}

Đây là DAL hay kho lưu trữ? Trong trường hợp này, tôi đoán là cả hai.

Kim


5
Đến bữa tiệc muộn ở đây, nhưng tại sao lại là T [], không phải là Danh sách <T> (hoặc tương tự)?
Mike Kingscott

27
Có lẽ IEnumerable <T> sẽ là tốt nhất.
Venemo

9
hoặc IQueryable <T>
kenwarner

1
Tôi nghĩ IQueryable <T> sẽ là lựa chọn tốt nhất, vì nó cho phép bạn xâu chuỗi các phương thức và trì hoãn thực thi để cơ sở dữ liệu thực hiện tất cả công việc.
0lukasz0

4
@kenwarner Tôi nghĩ việc trả về IQueryable <T> làm rò rỉ phần trừu tượng. Bạn nên trả về các đối tượng miền từ kho lưu trữ của mình.
Matthew

42

Kho lưu trữ là một mẫu có thể được áp dụng theo nhiều cách khác nhau, trong khi lớp truy cập dữ liệu có trách nhiệm rất rõ ràng: DAL phải biết cách kết nối với bộ lưu trữ dữ liệu của bạn để thực hiện các hoạt động CRUD.

Một kho lưu trữ có thể là một DAL, nhưng nó cũng có thể nằm trước DAL và hoạt động như một cầu nối giữa lớp đối tượng nghiệp vụ và lớp dữ liệu. Việc triển khai nào được sử dụng sẽ thay đổi theo từng dự án.


23

Một điểm khác biệt lớn là DAO là một cách chung để giải quyết vấn đề tồn tại cho bất kỳ thực thể nào trong miền của bạn. Mặt khác, một kho lưu trữ chỉ xử lý các gốc tổng hợp.


26
Điều đầu tiên cần hiểu là kho lưu trữ như một mẫu là một phần của hệ thống lớn hơn được gọi là Thiết kế theo hướng miền. Trong miền DDD, các đối tượng được nhóm thành các tập hợp, mỗi đối tượng có một gốc tổng hợp. Ví dụ: PurchaseOrder là một gốc tổng hợp và OrderItems là con trong gốc tổng hợp. Kho lưu trữ chỉ xử lý các gốc tổng hợp. Có nghĩa là, một OrderItem chẳng hạn không bao giờ được tải độc lập với gốc tổng hợp của nó. Vì vậy, bạn sẽ không bao giờ có một kho lưu trữ OrderItem trong DDD. Tuy nhiên, trong một hệ thống không DDD, bạn có thể có OrderItemDao vì Dao không bị giới hạn ở các gốc tổng hợp.
Aoermatic 23/12/09

NG, Cảm ơn! Tôi đã bắt đầu thấy nó theo cách đó, nhưng điều này làm cho nó rõ ràng. Tôi sẽ phải bắt đầu đọc tất cả các tài liệu DDD!
David

@bingle, mô tả tuyệt vời về các gốc tổng hợp và cách các đối tượng con được tải bởi một kho lưu trữ. Nơi nào sẽ tồn tại một kho lưu trữ trong một ứng dụng nhiều lớp? Tôi có thể thấy nó nằm trong thư viện lớp truy cập dữ liệu nhưng vì nó tải các đối tượng con, thay vào đó nó có nên tồn tại trong thư viện lớp logic không? Ruột của tôi cho tôi biết lớp truy cập dữ liệu nhưng tôi muốn ý kiến ​​của bạn về vấn đề này.
Jeff LaFay

12

Tôi đang tìm kiếm câu trả lời cho một câu hỏi tương tự và đồng ý với hai câu trả lời được xếp hạng cao nhất. Cố gắng làm rõ điều này cho bản thân tôi, tôi nhận thấy rằng nếu Đặc điểm kỹ thuật, đi đôi với mẫu Kho lưu trữ, được triển khai như các thành viên hạng nhất của mô hình miền, thì tôi có thể

  • sử dụng lại các định nghĩa Đặc điểm kỹ thuật với các tham số khác nhau,
  • thao tác các tham số của phiên bản Đặc điểm kỹ thuật hiện có (ví dụ: chuyên môn hóa),
  • kết hợp chúng,
  • thực hiện logic nghiệp vụ trên chúng mà không cần phải thực hiện bất kỳ quyền truy cập cơ sở dữ liệu nào,
  • và tất nhiên, unit-test chúng độc lập với việc triển khai Repository thực tế.

Tôi thậm chí có thể đi xa hơn và tuyên bố rằng trừ khi mẫu Kho lưu trữ được sử dụng cùng với mẫu Đặc tả, nó không thực sự là "Kho lưu trữ", mà là một DAL. Một ví dụ tiếp theo trong mã giả:

specification100 = new AccountHasMoreOrdersThan(100)
specification200 = new AccountHasMoreOrdersThan(200)

assert that specification200.isSpecialCaseOf(specification100)

specificationAge = new AccountIsOlderThan('2000-01-01')

combinedSpec = new CompositeSpecification(
    SpecificationOperator.And, specification200, specificationAge)

for each account in Repository<Account>.GetAllSatisfying(combinedSpec)
    assert that account.Created < '2000-01-01'
    assert that account.Orders.Count > 200

Xem Bài luận về Đặc điểm kỹ thuật của Fowler để biết chi tiết (đó là những gì tôi dựa trên phần trên).

Một DAL sẽ có các phương pháp chuyên biệt như

IoCManager.InstanceFor<IAccountDAO>()
    .GetAccountsWithAtLeastOrdersAndCreatedBefore(200, '2000-01-01')

Bạn có thể thấy điều này có thể nhanh chóng trở nên cồng kềnh như thế nào, đặc biệt là vì bạn phải xác định từng giao diện DAL / DAO với cách tiếp cận này triển khai phương pháp truy vấn DAL.

Trong .NET, các truy vấn LINQ có thể là một cách để triển khai các thông số kỹ thuật, nhưng việc kết hợp Đặc điểm kỹ thuật (biểu thức) có thể không trơn tru như với một giải pháp tự trồng. Một số ý tưởng cho điều đó được mô tả trong Câu hỏi SO này .


2

Ý kiến ​​cá nhân của tôi là tất cả về ánh xạ, xem: http://www.martinfowler.com/eaaCatalog/repository.html . Vì vậy, đầu ra / đầu vào từ kho lưu trữ là các đối tượng miền, mà trên DAL có thể là bất kỳ thứ gì. Đối với tôi, đó là một bổ sung / hạn chế quan trọng, vì bạn có thể thêm triển khai kho lưu trữ cho cơ sở dữ liệu / dịch vụ / bất cứ thứ gì với bố cục khác và bạn có một nơi rõ ràng để tập trung vào việc lập bản đồ. Nếu bạn không sử dụng hạn chế đó và có ánh xạ ở nơi khác, thì việc có các cách khác nhau để biểu diễn dữ liệu có thể ảnh hưởng đến mã ở những nơi mà nó không nên thay đổi.


1

Đó là tất cả về diễn giải và bối cảnh. Chúng có thể rất giống nhau hoặc thực sự rất khác nhau, nhưng miễn là giải pháp thực hiện công việc, thì đó là cái tên!


1

Kho lưu trữ là một mẫu, đây là một cách để triển khai mọi thứ theo cách chuẩn hóa để sử dụng lại mã khi chúng ta có thể.


1

Lợi thế của việc sử dụng mẫu kho lưu trữ là mô phỏng lớp truy cập dữ liệu của bạn, để bạn có thể kiểm tra mã lớp nghiệp vụ của mình mà không cần gọi mã DAL. Có những lợi thế lớn khác nhưng điều này dường như rất quan trọng đối với tôi.


1
Bạn vẫn có thể bắt chước một DAL, nó không cần phải là một kho lưu trữ. Điểm quan trọng là bất kỳ chiến lược truy cập dữ liệu nào bạn sử dụng, nó đều phải triển khai một giao diện. Điều này sẽ cho phép bạn sử dụng vùng chứa IoC cũng như kiểm tra mã doanh nghiệp của bạn một cách gọn gàng mà không cần đến kho dữ liệu.
cdaq,

0

Từ những gì tôi hiểu, chúng có thể có nghĩa về cơ bản giống nhau - nhưng cách đặt tên khác nhau dựa trên ngữ cảnh.

Ví dụ, bạn có thể có lớp Dal / Dao triển khai giao diện IRepository.

Dal / Dao là một thuật ngữ lớp dữ liệu; các cấp cao hơn của ứng dụng của bạn nghĩ về Kho lưu trữ.


0

Vì vậy, trong hầu hết các trường hợp (đơn giản), DAO là một triển khai của Kho lưu trữ?

Theo như tôi hiểu, có vẻ như DAO xử lý chính xác với quyền truy cập db (CRUD - Không có lựa chọn mặc dù ?!) trong khi Kho lưu trữ cho phép bạn tóm tắt toàn bộ quyền truy cập dữ liệu, có lẽ là một mặt tiền cho nhiều DAO (có thể là các nguồn dữ liệu khác nhau).

Tôi có đang đi đúng đường không?


Trên thực tế, tôi muốn đảo ngược điều đó và nói rằng từ một quan điểm đơn giản, Kho lưu trữ là một phong cách triển khai cụ thể cho một DAO, nhưng vâng, bạn đang đi đúng hướng. (R từ CRUD = Đọc, vì vậy đó là lựa chọn của bạn.)
Jeromy Irvine,

0

Trong thế giới bên ngoài (tức là mã máy khách), kho lưu trữ giống như DAL, ngoại trừ:

(1) các phương thức chèn / cập nhật / xóa bị hạn chế để có đối tượng vùng chứa dữ liệu làm tham số.

(2) đối với hoạt động đọc, nó có thể có đặc điểm kỹ thuật đơn giản như DAL (ví dụ: GetByPK) hoặc thông số kỹ thuật nâng cao.

Bên trong nó hoạt động với Lớp bản đồ dữ liệu (ví dụ: ngữ cảnh khung thực thể, v.v.) để thực hiện hoạt động CRUD thực tế.

Mẫu kho lưu trữ không có nghĩa là gì: -

Ngoài ra, tôi đã thấy mọi người thường nhầm lẫn khi có một phương thức Lưu riêng biệt làm phương thức triển khai mẫu kho lưu trữ bên cạnh các phương thức Chèn / Cập nhật / Xóa cam kết tất cả các thay đổi trong bộ nhớ được thực hiện bởi các phương thức chèn / cập nhật / xóa vào cơ sở dữ liệu. Chúng ta chắc chắn có thể có một phương thức Lưu trong một kho lưu trữ, nhưng đó không phải là trách nhiệm của kho lưu trữ để cô lập CUD trong bộ nhớ (Tạo, Cập nhật, Xóa) và các phương thức liên tục (thực hiện thao tác ghi / thay đổi thực tế trong cơ sở dữ liệu), nhưng trách nhiệm của mẫu Unit Of Work.

Hi vọng điêu nay co ich!


0

Người ta có thể tranh luận rằng "kho lưu trữ" là một lớp cụ thể và "DAL" là toàn bộ lớp bao gồm các kho lưu trữ, DTO, các lớp tiện ích và bất kỳ thứ gì khác được yêu cầ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.