Trước tiên, bạn nên để lộ giao diện để có được tham chiếu đến Tổng hợp gốc của bạn (ví dụ: Order()). Sử dụng mẫu Nhà máy để tạo mới một phiên bản mới của Tổng hợp gốc (ví dụ: Order()).
Với điều đó đã nói, các phương pháp trên các đối tượng Tổng hợp gốc của bạn truy cập vào các đối tượng liên quan - không phải chính nó. Ngoài ra, không bao giờ để lộ một loại phức tạp như công khai trên các gốc tổng hợp (nghĩa là bộ sưu tập IList của dòng() mà bạn đã nêu trong ví dụ). Điều này vi phạm pháp luật của decremeter (sp ck), mà nói rằng bạn không thể "Dot Walk" theo cách của bạn để phương pháp, chẳng hạn như Order.Lines.Add().
Và ngoài ra, bạn vi phạm quy tắc cho phép khách hàng truy cập tham chiếu đến đối tượng nội bộ trên Tổng hợp gốc. Các rễ tổng hợp có thể trả về một tham chiếu của một đối tượng bên trong. Miễn là, máy khách bên ngoài không được phép giữ một tham chiếu đến đối tượng đó. Tức là, "OrderLine" của bạn, bạn chuyển vào RemoveLine(). Bạn không thể cho phép khách hàng bên ngoài kiểm soát trạng thái nội bộ của mô hình của bạn (ví dụ: Order() và OrderLines()). Do đó, bạn nên mong đợi OrderLine là một cá thể mới để hành động theo đó.
public interface IOrderRepository
{
Order GetOrderByWhatever();
}
internal interface IOrderLineRepository
{
OrderLines GetOrderLines();
void RemoveOrderLine(OrderLine line);
}
public class Order
{
private IOrderRepository orderRepository;
private IOrderLineRepository orderLineRepository;
internal Order()
{
// constructors should be not be exposed in your model.
// Use the Factory method to construct your complex Aggregate
// Roots. And/or use a container factory, like Castle Windsor
orderRepository =
ComponentFactory.GetInstanceOf<IOrderRepository>();
orderLineRepository =
ComponentFactory.GetInstanceOf<IOrderLineRepository>();
}
// you are allowed to expose this Lines property within your domain.
internal IList<OrderLines> Lines { get; set; }
public RemoveOrderLine(OrderLine line)
{
if (this.Lines.Exists(line))
{
orderLineRepository.RemoveOrderLine(line);
}
}
}
Đừng quên nhà máy của bạn để tạo ra các trường hợp mới của Dòng():
public class OrderFactory
{
public Order CreateComponent(Type type)
{
// Create your new Order.Lines() here, if need be.
// Then, create an instance of your Order() type.
}
}
khách hàng bên ngoài của bạn không có quyền truy cập vào IOrderLinesRepository trực tiếp, thông qua giao diện để có được một tài liệu tham khảo của đối tượng giá trị trong Gốc tổng hợp của bạn. Nhưng, tôi cố gắng ngăn chặn điều đó bằng cách buộc tất cả các tham chiếu của tôi bị loại khỏi các phương thức của Tổng hợp. Vì vậy, bạn có thể đánh dấu IOrderLineRepository ở trên là nội bộ để nó không bị lộ ra.
Tôi thực sự nhóm tất cả các sáng tạo Tổng hợp của tôi vào nhiều Nhà máy. Tôi không thích cách tiếp cận của, "Một số rễ tổng hợp sẽ có các nhà máy cho các loại phức tạp, những người khác sẽ không". Dễ dàng hơn nhiều để có cùng một logic theo sau trong suốt mô hình miền. "Ồ, do đó, Sales() là một gốc tổng hợp như Order(). Phải có một nhà máy cho nó quá." Một lưu ý cuối cùng là nếu có sự kết hợp, tức là SalesOrder(), sử dụng hai mô hình Bán hàng() và Order(), bạn sẽ sử dụng một Dịch vụ để tạo và hành động trên trường hợp đó của SalesOrder() như không phải là Roots() hoặc Order() tổng hợp Roots, cũng không phải kho hoặc nhà máy của họ, tự kiểm soát thực thể SalesOrder().
Tôi đánh giá cao, khuyên bạn nên this free book bởi Abel Avram và Floyd Marinescu trên Thiết kế Drive Domain (DDD) vì nó trực tiếp trả lời câu hỏi của bạn, trong bản in khổ lớn 100 trang. Cùng với cách tách nhiều thực thể miền của bạn thành các mô-đun và như vậy.
Edit: thêm mã hơn
Tôi cho rằng sự mở rộng này có nghĩa là bạn không sử dụng ORM trực tiếp trên các thực thể miền của bạn. Tôi đã hy vọng để có thể tránh được công việc thêm bạn mô tả ở trên, bằng cách có linq để sql tự động tồn tại những thay đổi tôi thực hiện đối tượng tên miền ... –
y, đó là vấn đề thực sự. Tôi đã làm như trên. Tôi thường xuyên thấy bình luận trên Nhibernate hỗ trợ nhiều kịch bản nâng cao hơn, nhưng tôi chưa xem xét cách chơi với kiểu kịch bản này (không chỉ sử dụng POCO) – eglasius
Cảm ơn bạn; mặc dù không phải là lý tưởng khủng khiếp (lỗi của LTS, không phải câu trả lời của bạn) điều này dường như để xác nhận linh cảm của riêng tôi về cách tôi cần phải làm điều này ... – Funka