Vì vậy, sau khi đọc "Triển khai thiết kế hướng tên miền của Vaughn Vernon", tôi đã quyết định cấu trúc lại mã của mình để có thể sử dụng lại tốt hơn bằng cách tách biệt những gì tôi tin là các khái niệm miền cốt lõi thành các mô-đun riêng biệt.
Mỗi mô-đun chứa tập hợp các lớp kiến trúc riêng biệt bao gồm Lớp Miền, Cơ sở hạ tầng và Lớp Ứng dụng / Trình bày (theo khuyến nghị của Vaughn, tôi đã quyết định tách biệt trách nhiệm của lớp Ứng dụng khỏi các tuyến đường, các bộ điều khiển MVC + các mẫu tồn tại trong Lớp trình bày).
Tôi đã quyết định đặt từng lớp trong gói riêng của chúng; và mỗi gói được tham chiếu lớp bên dưới nó như là một phụ thuộc. tức là: Lớp trình bày phụ thuộc vào Lớp ứng dụng, Ứng dụng phụ thuộc vào Cơ sở hạ tầng, v.v. Vì Kho lưu trữ là một phần của Miền, mỗi Giao diện Kho lưu trữ tồn tại trong lớp / gói Miền với trách nhiệm của lớp / gói Cơ sở hạ tầng (Doctrine , Vân vân).
Tôi hy vọng rằng bằng cách cấu trúc lại mã của mình theo cách này, tôi sẽ có thể trao đổi lớp Ứng dụng và sử dụng lại Miền của mình trên nhiều Ứng dụng Web.
Mã cuối cùng trông giống như nó bắt đầu định hình lại tuy nhiên điều vẫn làm tôi bối rối là sự khác biệt giữa Ứng dụng, Cơ sở hạ tầng và Dịch vụ Miền.
Một ví dụ phổ biến của Dịch vụ miền là thứ mà bạn sẽ sử dụng để băm mật khẩu. Điều này có ý nghĩa với tôi từ góc độ SRP vì thực thể Người dùng không nên quan tâm đến nhiều thuật toán băm khác nhau có thể được sử dụng để lưu trữ thông tin đăng nhập của người dùng.
Vì vậy, trong tâm trí đó, tôi đã đối xử với dịch vụ Tên miền mới này giống như Kho lưu trữ của tôi; bằng cách xác định một giao diện trong Miền và để lại việc triển khai đến lớp Cơ sở hạ tầng. Tuy nhiên, bây giờ tôi đang tự hỏi về những gì nên được thực hiện với Dịch vụ ứng dụng.
Hiện tại, mỗi Thực thể có Dịch vụ Ứng dụng riêng, tức là Thực thể Người dùng có Dịch vụ Người dùng trong Lớp Ứng dụng. UserService trong trường hợp này chịu trách nhiệm phân tích các kiểu dữ liệu nguyên thủy và xử lý một trường hợp sử dụng chung "UserService :: CreatUser (tên chuỗi, email chuỗi, v.v.): Người dùng.
Điều tôi quan tâm là thực tế là tôi sẽ cần triển khai lại logic này trên nhiều ứng dụng nếu tôi quyết định trao đổi lớp Ứng dụng. Vì vậy, tôi đoán điều này dẫn tôi đến một vài câu hỏi tiếp theo:
Có phải các Dịch vụ Miền chỉ là một Giao diện tồn tại để cung cấp một lớp trừu tượng giữa Lớp Cơ sở hạ tầng và Mô hình của bạn? tức là: Kho lưu trữ + HashingService, v.v.
Tôi đã đề cập đến việc có một Dịch vụ Ứng dụng trông như thế này:
Truy cập / Ứng dụng / Dịch vụ / UserService :: CreatUser (tên chuỗi, email chuỗi, v.v.): Người dùng
Chữ ký phương thức chấp nhận các đối số kiểu dữ liệu nguyên thủy và trả về một Thực thể người dùng mới (không phải là DTO!).
Điều này có thuộc về lớp Cơ sở hạ tầng như là một triển khai của một số giao diện được xác định trong lớp Miền hoặc trên thực tế là Lớp ứng dụng phù hợp hơn do các đối số kiểu dữ liệu nguyên thủy, v.v. ?
thí dụ:
Access/Domain/Services/UserServiceInterface
và
Access/Infrastructure/Services/UserService implements UserServiceInterface
Làm thế nào các mô-đun riêng biệt nên xử lý các mối quan hệ đơn hướng. Lớp ứng dụng của mô-đun tham chiếu B (như hiện tại) hay triển khai cơ sở hạ tầng (thông qua giao diện riêng biệt)?
Các dịch vụ lớp ứng dụng có yêu cầu một giao diện riêng không? Nếu câu trả lời là có thì chúng nên được đặt ở đâu?