2009-12-29 66 views
12

Ưu điểm:Ưu điểm và nhược điểm của DDD Repositories

  • Repositories ẩn truy vấn phức tạp.
  • Phương thức lưu trữ có thể được sử dụng làm ranh giới giao dịch.
  • ORM có thể dễ dàng được chế giễu

Nhược điểm:

  • khuôn khổ ORM cung cấp đã là một bộ sưu tập như giao diện để đối tượng liên tục, mục đích của kho là gì. Vì vậy, kho lưu trữ thêm phức tạp thêm vào hệ thống.
  • vụ nổ tổ hợp khi sử dụng phương pháp findBy. Những phương pháp này có thể tránh được với các đối tượng tiêu chí, truy vấn hoặc đối tượng ví dụ. Nhưng để làm điều đó không có kho lưu trữ là cần thiết vì một ORM đã hỗ trợ những cách này để tìm các đối tượng.
  • Vì kho là tập hợp các rễ tổng hợp (theo nghĩa DDD), người ta phải tạo và truyền xung quanh rễ tổng hợp ngay cả khi chỉ có một đối tượng con được sửa đổi.

Câu hỏi:

  • gì ưu và nhược điểm nào bạn biết?
  • Bạn có đề xuất sử dụng kho lưu trữ không? (Tại sao hoặc tại sao không?)
+2

ORM tương phản với kho lưu trữ không thực sự có ý nghĩa - bạn sử dụng ORM để triển khai kho, không? –

+1

Không có câu trả lời rõ ràng. Cộng đồng wiki? –

+1

Con thứ ba của bạn không có ý nghĩa. Nếu bạn cần phải thao tác một "đối tượng con" một mình, nó phải là một gốc tổng hợp. –

Trả lời

8

Điểm chính của kho lưu trữ (như trong Nguyên tắc về trách nhiệm duy nhất) là trừu tượng hóa khái niệm về việc nhận các đối tượng có nhận dạng. Khi tôi đã trở nên thoải mái hơn với DDD, tôi đã không thấy hữu ích khi nghĩ về kho lưu trữ chủ yếu tập trung vào sự kiên trì dữ liệu mà thay vào đó là các nhà máy khởi tạo các đối tượng và duy trì danh tính của chúng.

Khi bạn đang sử dụng ORM, bạn nên sử dụng API của mình một cách hạn chế nhất có thể, tạo cho mình một mặt tiền có lẽ đó là miền cụ thể. Vì vậy, bất kể tên miền của bạn sẽ vẫn chỉ thấy một kho lưu trữ. Thực tế là nó có một ORM ở phía bên kia là một "chi tiết thực hiện".

7

Kho lưu trữ thực sự chỉ là một lớp trừu tượng, như giao diện. Bạn sử dụng nó khi bạn muốn tách riêng triển khai dữ liệu của bạn (tức là cơ sở dữ liệu của bạn).

Tôi cho rằng nếu bạn không muốn tách DAL của mình, thì bạn không cần kho lưu trữ. Nhưng có nhiều lợi ích để làm như vậy, chẳng hạn như testability.

Về sự bùng nổ tổ hợp của phương thức "Tìm": trong .NET bạn có thể trả về IQueryable thay vì IEnumerable và cho phép ứng dụng khách gọi chạy truy vấn LINQ trên đó thay vì sử dụng phương thức Tìm. Điều này cung cấp sự linh hoạt cho khách hàng, nhưng hy sinh khả năng cung cấp một giao diện có thể kiểm tra được xác định rõ ràng. Về cơ bản, bạn trao đổi một bộ lợi ích cho một tập hợp lợi ích khác.

+1

+1 khi trả lại một IQueryable từ IRepository. Điều này cho phép bạn viết logic "tìm" của bạn trong lớp dịch vụ/root và kiểm tra logic đó bằng cách mô phỏng một IRepository. Để kiểm tra, lớp "Repository" là nơi tôi vẽ đường thẳng giữa kiểm thử Đơn vị và Kiểm thử tích hợp - Tôi viết các kiểm tra Tích hợp cho Repos của tôi và trả về các bản ghi FetchAll() thích hợp cho một IQueryable và các bài kiểm tra Đơn vị cho eveything khác có logic kinh doanh thực tế trong đó. – eduncan911

+0

Ít nhất với NHibernate bạn phải biết rằng có sự khác biệt lớn (caching, cách truy vấn được thực hiện) giữa gọi linq .Where (a => a.id == id) và gọi ISession.Load (id). Nó có thể hữu ích để có một cách IQueryable để truy cập dữ liệu, nhưng không cố gắng làm mọi thứ với nó, hãy nhớ rằng ORM thường cung cấp một vài cách để thực hiện các truy vấn và hoạt động nâng cao. –

8

Kho lưu trữ đưa mô hình miền vào tiêu điểm bằng cách ẩn chi tiết truy cập dữ liệu phía sau giao diện dựa trên ngôn ngữ phổ biến. Khi thiết kế kho lưu trữ, bạn tập trung vào các khái niệm miền, không tập trung vào truy cập dữ liệu. Từ quan điểm DDD, việc sử dụng API ORM trực tiếp tương đương với việc sử dụng SQL trực tiếp.

Đây là cách kho có thể trông giống như trong các ứng dụng xử lý đơn hàng:

List<Order> myOrders = Orders.FindPending() 

Lưu ý rằng không có điều kiện truy cập dữ liệu như 'Tiêu chuẩn' hoặc 'Query'. Phương pháp 'FindPending' nội bộ có thể được thực hiện bằng cách sử dụng Hibernate Criteria hoặc HQL nhưng điều này không liên quan gì đến DDD.

Phương thức nổ là mối quan tâm hợp lệ. Ví dụ: bạn có thể kết thúc với nhiều phương pháp như:

Orders.FindPending() 
    Orders.FindPendingByDate(DateTime from, DateTime to) 
    Orders.FindPendingByAmount(Money amount) 
    Orders.FindShipped() 
    Orders.FindShippedOn(DateTime shippedDate) 
    etc 

Điều này có thể được cải thiện bằng cách sử dụng mẫu Đặc điểm kỹ thuật. Ví dụ, bạn có thể có một lớp

class PendingOrderSpecification{ 
    PendingOrderSpecification WithAmount(Money amount); 
    PendingOrderSpecification WithDate(DateTime from, DateTime to) 
    ... 
} 

Vì vậy, kho mà sẽ trông như thế này:

Orders.FindSatisfying(PendingOrderSpecification pendingSpec) 
Orders.FindSatisfying(ShippedOrderSpecification shippedSpec) 

Một lựa chọn khác là phải có kho riêng cho Pending và đơn đặt hàng vận chuyển.

Các vấn đề liên quan