Các đối tượng miền trong Thiết kế hướng miền chỉ được coi là chỉ ghi?


13

Tôi đã đọc về Thiết kế hướng miền trong gần hai năm và đã thận trọng giới thiệu một số khái niệm trong công việc hàng ngày của tôi hoặc ít nhất là lập kế hoạch cho những việc tôi làm thường xuyên có thể được thực hiện trong Thiết kế hướng miền.

Một kết luận mà tôi bắt đầu đi đến đặc biệt là phản ứng với việc đọc thêm về Phân chia trách nhiệm truy vấn lệnh và truy vấn lệnh (CQRS) rằng có lẽ các đối tượng miền chỉ được sử dụng cho mục đích ghi. Nói rõ hơn, dường như những gì mọi người gợi ý một cách tinh tế trong phần lớn tài liệu tôi đã đọc rằng các đối tượng miền chịu trách nhiệm thực hiện các hoạt động / tính toán tập trung vào miền, sau đó chủ yếu cung cấp một con đường để kiên trì thông qua cơ sở hạ tầng được cung cấp trong một triển khai Kho lưu trữ. Mặc dù tôi thích thực tế rằng điều này có thể đơn giản hóa rất nhiều mô hình miền vì nó cắt giảm trách nhiệm phơi bày trạng thái.

Nếu thực sự đúng là các đối tượng miền chủ yếu được sử dụng làm đối tượng chỉ ghi thì điều đó đặt ra một số câu hỏi cho tôi mà tôi hy vọng ai đó có thể trả lời.

  1. Làm thế nào để một người thực hiện kiểm tra đơn vị trên một đối tượng có setters hoặc phương thức sửa đổi trạng thái của đối tượng nhưng không cung cấp giao diện công khai ra bên ngoài để đọc trạng thái từ như các thuộc tính trong C #? Có thể phơi bày trạng thái chỉ với mục đích làm cho đối tượng đó có thể kiểm tra được không?
  2. Làm thế nào để hiển thị cho người dùng kết quả tính toán hoặc thao tác được thực hiện trong miền mà không phải duy trì chúng và sau đó kéo kết quả từ lưu trữ liên tục bên ngoài ngữ cảnh của miền? Có ổn không khi để lộ trạng thái chỉ với mục đích hiển thị kết quả.

Là quy tắc của ngón tay cái mà các getters tài sản duy nhất (có được người truy cập) nên là những người cũng có thể ghi trong miền? Hoặc nói khác nhau nên các thuộc tính chỉ đọc là điều duy nhất cần tránh vì chúng chỉ ở đó cho mục đích đọc và do đó không đóng vai trò cần thiết trong mô hình miền thực tế?

Tài liệu liên quan:

  1. TDD, DDD và đóng gói

Câu trả lời:


9

Không chắc chắn rằng có một câu trả lời "một cách đúng" cho cách tiếp cận thiết kế, công bằng mà nói, vẫn đang phát triển. Đầu tiên, DDD và CQRS không giống nhau mặc dù những người CQRS dường như đã bắt nguồn từ điểm bắt đầu chịu ảnh hưởng của DDD.

Có rất nhiều điều xảy ra trong suy nghĩ DDD và phần lớn phải làm với các ranh giới được xác định đúng của các vấn đề, giao tiếp giữa các bên liên quan và tương tác giữa các hệ thống, không nhất thiết phải là một triển khai cụ thể trong mã, vì vậy tôi không nghĩ là quá khó- cốt lõi là một đức tính.

Bạn có thể đang thấy một số cuộc tranh luận xung quanh việc liệu các đối tượng miền có thể thay đổi được hay không và chức năng của một đối tượng miền phục vụ trong toàn bộ hệ thống. CQRS chia một hệ thống thành các đường dẫn đọc và viết, do đó, có thể kết luận rằng bạn không thực sự cần truy cập đọc khi bạn đang trên đường viết. Đọc sau đó trở thành một cái gì đó bạn làm chống lại các sự kiện được nêu ra bởi một số đối tượng miền và được tiêu thụ (xử lý) bởi những người khác. Nếu bạn quay lại một chút trong lịch sử CQRS, bạn sẽ tìm thấy các đối số rằng các đối tượng miền không nên có setters, chỉ có getters và một phương thức 'xử lý' duy nhất. Logic ở đây là chỉ tiêu thụ các sự kiện mới dẫn đến thay đổi trạng thái và thay đổi đó hoàn toàn được xử lý bên trong bởi đối tượng miền.

Bạn hiển thị kết quả của sự thay đổi bằng cách coi chúng là các tạo tác riêng biệt của sự thay đổi, đặt chúng vào một cấu trúc bền vững riêng biệt (ví dụ: bảng) và đọc nó như thể bạn chỉ đọc một báo cáo về trạng thái hiện tại và lịch sử của hệ thống . Ví dụ: bạn có thể sử dụng một sự kiện bằng cách trích xuất dữ liệu bạn cần đọc và lưu nó vào bảng cơ sở dữ liệu ánh xạ sát với một chế độ xem (ví dụ: màn hình) của hệ thống.

Nếu bạn thử nghiệm phong cách này, hãy nhận thức rằng các lập trình viên khác có thể sẽ không quen thuộc với phương pháp này và có rất ít kịch bản (nhưng thú vị) trong đó có thể coi là phương pháp thiết kế.

Đối với thử nghiệm đơn vị, có một vài cách tiếp cận có thể phù hợp với bạn. Điều đầu tiên và tự nhiên nhất là xác minh các sự kiện mà bạn mong đợi được thấy bởi các đối tượng miền của bạn là chính xác. Một đối tượng miền có thể đưa ra một sự kiện thay đổi chung chứa thông tin về sự thay đổi. Bạn có thể xác minh rằng. Bạn có thể xác minh thực tế rằng sự kiện này đã được nêu ra và các sự kiện khác không được nêu ra.

Một cách tiếp cận khác là sử dụng các điệp viên thử nghiệm phơi bày các thuộc tính có thể đọc được trên đối tượng miền của bạn để bạn có thể xác minh các thay đổi trạng thái. Chẳng hạn, bạn có thể kế thừa từ đối tượng miền của mình, thêm một số người truy cập để đọc trạng thái được đóng gói và xác minh rằng điều đó đúng.

Một lần nữa, bạn bối rối vì những cách tiếp cận này là khó hiểu. Nếu bạn đang muốn áp dụng một số ý tưởng hay vào lập trình của mình, trước tiên hãy lấy các bit ngon ngọt. Ranh giới DDD và làm cho vai trò rõ ràng là những thay đổi trong cách suy nghĩ của bạn về việc giao tiếp với mã của bạn. CQRS ở mức tối thiểu cho thấy rằng đọc dữ liệu và ghi dữ liệu là các hoạt động tách biệt. Cái nhìn sâu sắc đó khiến bạn suy nghĩ rất rõ ràng về vai trò của dữ liệu bạn cần trình bày là gì, bạn thực sự cần bao nhiêu, ai đang tiêu thụ nó, cần phải tươi như thế nào, v.v ... Bạn không cần triển khai Tìm kiếm sự kiện đầy đủ để áp dụng đóng gói tốt hơn trong mã hóa của bạn. Bạn có thể bắt đầu bằng cách chỉ tập trung vào các hoạt động nguyên tử trong đối tượng của mình, cách tiếp cận "Nói, không hỏi" đối với thiết kế giao diện đối tượng,


1
+1 để bắt đầu với các bit jucy. Ngoài ra: cắn chỉ CQS (bỏ qua phần 'sự kiện' bây giờ) có thể là một nơi tốt để bắt đầu.
cottsak

1

Các đối tượng miền trong Thiết kế hướng miền chỉ được coi là chỉ ghi?

Số CQRS có thể được sử dụng cùng với DDD.


Nhưng phần Truy vấn của CQRS có phải là tất cả về truy vấn dữ liệu được sử dụng bởi mô hình miền để ghi các thay đổi cho mô hình hoặc có thể được sử dụng để truy vấn dữ liệu cho lớp ứng dụng có thể hiển thị các giá trị cho người dùng không? Tôi nghe được từ một số người rằng DDD là tất cả về việc điều phối các thay đổi và không nên được sử dụng để đọc từ bất kỳ mục đích nào khác ngoài việc phối hợp các thay đổi với một đối tượng khác trong mô hình miền. Quyết định theo cách này hay cách khác có nghĩa là một thiết kế mô hình hoàn toàn khác biệt khi thấy rằng dữ liệu được hiển thị trên các đối tượng miền sẽ bị hạn chế khác nhau nếu nó chỉ được sử dụng trong miền.
jpierson

0

Các bài kiểm tra đơn vị mô hình miền của bạn nên kiểm tra xem mỗi lệnh đã thực thi các sự kiện miền chính xác được nêu ra chưa. Các lệnh miền và các sự kiện đã bắt của bạn có thể được thẩm vấn cho trạng thái.

Bạn cũng có thể ghi đè lên ToString()các lệnh và sự kiện trong miền để cung cấp báo cáo trạng thái tự động, dễ đọc cho con người.

Để trả lời câu hỏi thứ hai của bạn, để hiển thị kết quả của các lệnh bạn nên sắp xếp để các sự kiện trong miền được 'xuất bản' cho mô hình đọc của bạn.


Bạn có thể giải thích một chút về việc liệu điều này có còn áp dụng khi bạn không sử dụng nguồn cung cấp sự kiện không?
jpierson

1
Không có nguồn sự kiện có lẽ đề nghị của tôi sẽ không hoạt động; Tôi không biết cách mã của bạn. Đối với một đối tượng miền lý tưởng không để lộ bất kỳ thuộc tính nào, có lẽ bạn có thể thực hiện rõ ràng một giao diện kiểm tra hiển thị các thuộc tính bạn muốn kiểm tra. Chỉ mã kiểm tra của bạn mới 'biết' để truyền các đối tượng miền như vậy vào giao diện kiểm tra.
Ed James

Cảm ơn lời đề nghị đó. Tôi cảm thấy hơi khó chịu về ý tưởng sửa đổi các lớp miền của mình cụ thể để kiểm tra nhưng tôi cho rằng đây có thể là một trong những khu vực màu xám vẫn còn trong Thiết kế hướng miền nếu bạn muốn nó có thể kiểm tra được. Một suy nghĩ khác là nếu một người để lộ sự ổn định và khả năng kiểm tra thông qua cùng một giao diện thì ít nhất bạn chỉ giới thiệu một phụ thuộc cơ sở hạ tầng thay vì hai. Người khác nghĩ gì về điều đó?
jpierson
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.