2013-07-31 24 views
8

Tôi đang có lần thử đầu tiên tại DDD và đang gặp sự cố với thiết kế tổng hợp.DDD - Thực thi bất biến với các rễ nhỏ tổng hợp

Ứng dụng của tôi chứa 3 Thực thể; Biểu đồ, Nút, Liên kết. Mỗi thực thể này có một thuộc tính tên có thể được sửa đổi bởi người dùng (mà tôi tin rằng làm cho 'tên' không phù hợp như là một id thực thể). Một biểu đồ chứa một tập hợp các nút và nút có một bộ sưu tập các liên kết đi (cho mục đích của vấn đề này là an toàn để bỏ qua các liên kết đến). Mỗi nút chỉ có thể được liên kết với một đồ thị tại một thời điểm (nhưng có thể di chuyển giữa các đồ thị) và tương tự, mỗi liên kết chỉ có thể được liên kết với một nút tại bất kỳ thời điểm nào (nhưng có thể được di chuyển).

(Các) bất biến mà tôi đang cố thực thi là tất cả các tên Thực thể là duy nhất trong bộ sưu tập gốc của chúng. Với kiến ​​trúc được mô tả ở trên, bất biến là trên các bộ sưu tập thực tế, vì vậy tôi đã quyết định rằng các chủ sở hữu bộ sưu tập (Graph và Node) cả hai nên là Tổng hợp Roots.

Vấn đề tôi có là làm cách nào để bây giờ tôi thực thi tên bất biến trên nút? Về Liên kết, nó rất dễ dàng vì nó được ẩn đi bên trong nút AR và như vậy nút có thể xác nhận rằng tất cả các liên kết đổi tên/di chuyển không phá vỡ bất biến này. Nhưng theo như tôi thấy, không có gì để ngăn chặn việc đổi tên trực tiếp của Node mà có thể phá vỡ bất biến. Sự nhất quán cuối cùng không phải là một lựa chọn chấp nhận được ở đây, đây phải là một sự bất biến của hệ thống thực sự.

Cách tiếp cận tôi đang xem xét là có Node.Rename() thực sự thực thi bất biến, nhưng mối quan tâm của tôi là điều này liên quan đến việc tìm kiếm bên trong biểu đồ chính để kiểm tra xem việc đổi tên có hợp lệ hay không. Điều này không 'cảm thấy' đúng - nó cảm thấy như đồ thị nên là một trong những thực thi ràng buộc này không gian tên và rằng Node nên biết gì về nó cả.

Tôi hy vọng điều này có ý nghĩa và tôi mong muốn được nghe suy nghĩ của mọi người.

Chỉnh sửa: Mô hình miền được trình bày ở trên là một tập hợp con được đơn giản hóa của toàn bộ miền. Quá phức tạp đối với tất cả các thực thể được tổ chức trong một AR duy nhất .......

+2

"có vẻ như Biểu đồ phải là một trong những thực thi ràng buộc về không gian tên này và Nút đó không biết gì về nó cả." - bingo! – MattDavey

+1

@MattDavey - Vậy bạn có gợi ý AR duy nhất nên là Biểu đồ không? Tôi không thấy làm thế nào khác tôi có thể thực thi rằng tất cả các đổi tên Node nên đi qua đồ thị cha mẹ. Nếu đây là trường hợp, tôi lo rằng tôi sẽ kết thúc với một AR khổng lồ 'thần' - tương tự như những nỗ lực đầu tiên trong [bài luận Vaughan] (http://dddcommunity.org/wp-content/uploads/files/pdf_articles /Vernon_2011_1.pdf) – tonyj444

+1

Nếu đó là một sự bất biến của hệ thống thực, việc giữ cho 'Đồ thị' là một AR có vẻ là con đường để đi. Nếu bạn sử dụng 'Đồ thị' làm AR duy nhất, thì nó có thể phát triển bao nhiêu và bạn dự kiến ​​sẽ có bao nhiêu đồng thời? – JefClaes

Trả lời

6

Giải pháp mà tôi gặp phải là do tiếp cận CQRS. Tôi tìm thấy một giới thiệu CQRS xuất sắc here.

Trong mô hình 'viết' của tôi; Biểu đồ, nút và liên kết là tất cả các Tổng hợp gốc, nhưng tên được quản lý hoàn toàn bằng bộ sưu tập gốc. Vì vậy, trong mô hình viết, một Node không có ý tưởng tên riêng của nó là gì (có nghĩa là các cập nhật tên phải đi qua đồ thị sở hữu). Trong mô hình 'đọc' tương ứng, tên được liên kết trực tiếp với nút (vì điều này hữu ích cho việc hiển thị).

Lợi thế của giải pháp này là nó cho phép tôi giữ AR nhỏ, nhưng vì thông tin 'tên' được giữ bên trong bộ sưu tập gốc, tôi không có vấn đề gì với việc duy trì các biến thể tổng hợp chéo.

+0

Rất vui khi biết bạn đã có thể giải quyết vấn đề của mình. Tôi đã đọc về CQRS là tốt, nhưng không bao giờ thực sự đưa nó vào thực tế. Nhưng có lẽ tôi nên, nó chắc chắn sẽ làm cho các phần của dự án của tôi dễ thực hiện hơn :) –

+0

Bạn có phương thức 'graph.renameNode (node, name)' hoặc 'node.renameChild (childNode, name)'? Thực hiện chính xác bằng cách nhận và thiết lập tên nút là gì? Bạn lưu trữ tên ở đâu? Chúng có thuộc tính nút hay không trong bộ sưu tập, ví dụ: tên -> bản đồ nút? – inf3rno

18

Như bạn đã kết luận trong nhận xét của bạn, thì chỉ tổng thể gốc nên là Đồ thị.

Có sự khác biệt giữa tổng hợp và tổng hợp rễ. Trong ví dụ của bạn cả Graph và Node đều là aggregates, nhưng đối tượng chịu trách nhiệm quản lý toàn bộ aggregate là Graph. Đây là gốc.

Cách dễ nhất để có được một ý tưởng nếu một đối tượng là một gốc tổng hợp là tự hỏi mình:

Liệu nó làm cho tinh thần để có chỉ đối tượng này, tách khỏi mẹ của nó?

Nếu câu trả lời là không, thì có thể không phải là thư mục gốc. Ví dụ, một Node đơn có lẽ là ít sử dụng khi nó không phải là một phần của một đồ thị mẹ. Đó là lý do tại sao bạn thường chỉ có kho cho rễ tổng hợp; để ngăn không cho bạn truy cập vào các đối tượng không phải là một phần của gốc tổng hợp tương ứng của chúng.

Hiện tại trên các biến thể.Bạn nói rằng (tôi nhấn mạnh):

tất cả [Node] tên là duy nhất trong cha mẹ của họ [Graph]

bạn về cơ bản đã trả lời câu hỏi của bạn ngay tại đó. Trong bối cảnh của một Node đơn, không có nghĩa gì khi nói rằng tên của nó là duy nhất. Nhưng trong ngữ cảnh của Biểu đồ, vì đó là bất biến của Biểu đồ, không phải Nút. Vì vậy, Biểu đồ chịu trách nhiệm cho protecting this invariant.

Đối với 'gốc tổng hợp thần', không có gì lạ khi có một gốc tổng hợp duy nhất từ ​​góc độ kinh doanh toàn cầu. Nhưng một khía cạnh quan trọng của DDD là xác định các bối cảnh khác nhau trong hệ thống. Hệ thống của bạn có thể có một thư mục gốc cấp cao chứa nhiều đối tượng Graph. Trong bối cảnh cấp cao này về quản lý biểu đồ của bạn, có thể bạn thậm chí không quan tâm đến các đối tượng Liên kết cấp thấp trong biểu đồ.

Điều quan trọng là bạn lập mô hình đối tượng miền của mình theo ngữ cảnh. Đây là một trong những điều quan trọng nhất tôi đã nhận ra trong vài tháng qua. Hầu hết mọi người đều biết về DDD vì các kho lưu trữ, hoặc có thể vì các thực thể và các đối tượng giá trị, nhưng chúng không quan trọng như các ngữ cảnh bị giới hạn.

Mặc dù chỉ có một khái niệm kinh doanh về Cái gì đó, nó là hoàn toàn tốt để có nhiều mô hình đại diện cho khái niệm Cái gì đó, một triển khai thực hiện cho mỗi ngữ cảnh. Một triển khai có thể là một gốc tổng hợp, trong khi triển khai khác chỉ là một phần của tổng hợp lớn hơn, tất cả phụ thuộc vào ngữ cảnh.

Các chú giải phần mềm phổ biến là về sử dụng lại mã, DRY và thích, vì vậy lúc đầu cảm thấy sai khi có nhiều lớp đại diện cho cùng một khái niệm kinh doanh. Nhưng một khi tôi đã có thể buông bỏ cảm giác này và nhận ra rằng mỗi sự thực hiện có trách nhiệm riêng của nó, nó làm mọi việc trở nên dễ dàng hơn nhiều :)

+1

"Hầu hết mọi người đều biết về DDD vì các kho lưu trữ, hoặc có thể vì các thực thể và các đối tượng giá trị, nhưng chúng không quan trọng như các ngữ cảnh bị chặn." - +1 Vâng, thưa ngài. – MattDavey

+3

Wow, vì vậy điều này đã loại thổi tâm trí của tôi. Tôi đã có ấn tượng rằng BCs về cơ bản là cho các ứng dụng khác nhau tạo thành một số tập con của toàn bộ hệ thống. Suy nghĩ về những thứ như thế này có phân nhánh đáng kể cho phần còn lại của mô hình miền của tôi. Điều này đã cho tôi rất nhiều suy nghĩ (và tìm hiểu) về. Mà chỉ có thể là một điều tốt. – tonyj444

+0

Đã thực hiện rất nhiều việc đào bới và đọc trên BC, tôi đã đưa ra một nguyên mẫu làm việc bằng cách sử dụng phương pháp này. Vấn đề tôi gặp phải là cần phải có rất nhiều thông tin liên lạc giữa 2 BCs có nghĩa là họ đã trở nên rất chặt chẽ và tôi bắt đầu nghi ngờ họ không còn là những BC thực sự nữa. Giải thích của bạn về nhiều mô hình đại diện cho một khái niệm duy nhất của một cái gì đó là một mắt mở lớn cho tôi mặc dù, và là những gì dẫn tôi đến CQRS, vì vậy cảm ơn một lần nữa! – tonyj444

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