Hướng dẫn cấu trúc dự án ứng dụng lớp MVVM, DDD và WPF


17

Tôi đang cố gắng thiết lập cấu trúc ứng dụng của mình trong VS và tôi muốn "thử" và chứng minh tương lai ở mức hợp lý. Ứng dụng này sẽ là bản viết lại WPF của một ứng dụng Winform cũ không tuân theo quy ước nào. Không có lớp, tầng, từ viết tắt, v.v ...

Nó là một ứng dụng doanh nghiệp khá lớn. Tôi đã lên kế hoạch sử dụng Linq To SQL làm DB của mình và rất có thể sẽ luôn là MS SQL. Ngoài ra tôi có một bộ kỹ năng hiện có với nó.

Tôi muốn theo dõi MVVM và DDD tốt nhất có thể nhưng tôi bị lẫn lộn về cấu trúc ứng dụng của mình khi kết hợp những thứ này. Hãy để tôi thử và minh họa với một số ví dụ.

Khi tôi theo MVVM, cấu trúc thư mục của tôi có thể trông như thế này:

Views
Models
ViewModels
Helpers

nhưng làm thế nào điều đó phù hợp với cách tiếp cận phân lớp DDD đơn giản trong đó Cấu trúc dự án của tôi có thể giống như thế này:

MyApp.UI
MyApp.Domain
MyApp.Data

Tôi có đặt Modelstrong lớp Miền hay tôi có 3 phiên bản nói Person? Điều này dẫn đến một câu hỏi khác về việc tôi sẽ đặt Kho lưu trữ và ánh xạ đối tượng DB của mình vào đối tượng miền ở đâu? Tôi sẽ giả sử dữ liệu ...

ViewsTôi nhận được sẽ đi trong UI nhưng ViewModelscũng sẽ ?

Cuối cùng, tôi sẽ nhúng Logic kinh doanh ở đâu?

Tôi đã tìm thấy những điều sau đây trên CodePlex, ví dụ DDD và nó có ích nhưng dường như là dành cho Ứng dụng web mặc dù điều đó có thể không quan trọng và sự thiếu hiểu biết của tôi tỏa sáng.

Đừng hiểu lầm tôi, tôi biết tôi có thể có nhiều thư mục và gọi chúng bất cứ thứ gì tôi muốn. Tôi đang cố gắng tìm ra nơi để đặt mọi thứ để điều này sẽ có thể mở rộng quy mô, chứ không phải những nơi đó nhất thiết phải được gọi.

Trọng tâm của câu hỏi của tôi có thể được hiển thị như thế này.
Tôi có tblPersonđối tượng được tạo bởi *.dbml. Điều này là hiển nhiên và sẽ thuộc về lớp "Dữ liệu" của tôi.
Bây giờ tôi sẽ có Model, DTO, Domain Model hoặc bất cứ thứ gì nó được gọi trong Lớp riêng biệt (dự án?) Được gọi Person. Tôi sẽ cần một Mappercho Personđến tblPersonmà tôi không chắc chắn nơi để đặt.
Sau đó, tôi sẽ có một ViewModel, giả sử, EditPersonnó sẽ có các thuộc tính riêng mà nó lấy từ Personnhưng có thể nhiều hơn nữa.
Cuối cùng, tôi có một Chế độ xem được ràng buộc với ViewModel đó ....

Để rõ ràng rằng đoạn đó được HOÀN TOÀN với các giả định và phỏng đoán của tôi và tôi hy vọng ai đó sẽ giúp làm sáng tỏ không khí cho tôi hoặc đưa ra những hiểu biết để 6 tháng đến một năm kể từ bây giờ tôi không tự đá mình nhiều hơn tôi cần.


Linq To SQL không phù hợp cho các dự án lớn hơn. Sử dụng Entity Framework hoặc ORM khác nhau như nHibernate. Ngoài ra, đây là ứng dụng chỉ dành cho khách hàng hay máy khách-máy chủ?
Euphoric

Nó là một ứng dụng chỉ dành cho khách hàng của WPF. Ngoài ra, bạn có thể giải thích lý do tại sao bạn cảm thấy L2S không phù hợp với ứng dụng có kích thước trung bình hoặc lớn hơn khi nguồn dữ liệu duy nhất của tôi là MS SQL không?
Khúc xạ Paladin

Câu trả lời:


5

MVVM là một mẫu UI và được sử dụng trong máy khách.

Các phần của miền trong DDD được sử dụng trong máy khách có thể là (một phần của) Mô hình

View và ViewModel chỉ là ứng dụng khách.

Tôi đặt Kho lưu trữ trong (hoặc gần) Mô hình vì chúng đồng bộ hóa Mô hình với mặt sau.

Có, nhiều lần điều này sẽ dẫn đến nhiều lớp Người trong các không gian tên khác nhau. Chúng có thể bắt đầu rất giống nhau nhưng có thể kết thúc rất khác sau một vài lần lặp hoặc phát hành.

BIÊN TẬP

Để làm rõ phần về Kho lưu trữ và để giải thích thêm về định vị của Logic nghiệp vụ

Nếu bạn đang tạo một hệ thống chứa một kho khách riêng biệt và phía máy chủ / back-end có thể được sử dụng trong máy khách và máy chủ. Trong máy khách để cung cấp một bản tóm tắt của (các) máy chủ và trong máy chủ để cung cấp một bản tóm tắt của các máy chủ và nguồn dữ liệu khác. Nó chỉ là một mô hình.

Đối với quy tắc Kinh doanh: nếu bạn sử dụng các quy tắc trong máy khách, hãy đảm bảo bạn cũng thực thi chúng trong máy chủ. Không bao giờ tin tưởng một khách hàng. Các quy tắc kinh doanh trong máy khách cho phép xác thực đầu vào nhanh chóng và ngăn các chuyến đi khứ hồi đến máy chủ.

Tôi nghĩ rằng DDD thuộc về phía máy chủ và 'rò rỉ' cho máy khách.


2

Bạn có hướng đúng trong việc chọn mẫu thiết kế MVVM cho ứng dụng WPF.

Do I put the Models in the Domain layer?

Có, mô hình của bạn có thể được đặt trong miền

Where would I put my Repository and mappings of DB Object to Domain Object?

Kho của bạn có thể được đặt trong lớp nơi Tên miền của bạn được đặt. Các đối tượng ánh xạ của bạn (còn được gọi là DTO - đối tượng chuyển miền) nên được đặt trong lớp dịch vụ của bạn và bạn có thể sử dụng công cụ ánh xạ mạnh mẽ AutoMapper để dễ dàng ánh xạ các đối tượng miền của bạn sang DTOs.

ViewModels also?

ViewModels của bạn nên được đặt ở phía máy khách của bạn (lớp). Bạn có thể xây dựng các chế độ xem của mình từ một hoặc nhiều DTO, tùy thuộc vào chế độ xem của bạn.

Về DDD , tôi khuyên bạn nên đọc về điều này và làm rõ cho bạn thực sự cần phải có mẫu Thiết kế hướng tên miền. Đây là một cuộc thảo luận rằng 95% tất cả các ứng dụng phần mềm rơi vào hệ thống không tốt cho việc sử dụng các danh mục DDD.

Chỉnh sửa: tham chiếu đã được thêm ở trên và cảm ơn đi cho @Den!


xin vui lòng, bình luận khi xuống bỏ phiếu.
Yusubov

1
Fanboys DDD muốn sử dụng nó ở khắp mọi nơi. Liên kết liên quan: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den

@Den, cảm ơn bạn đã liên kết! tôi đã lên kế hoạch tìm kiếm nó
Yusubov

1

Trước khi chúng ta đi sâu vào những gì đi đâu, hãy nói về những gì mỗi lớp nên làm.

Điểm bán hàng của MVVM là sự ràng buộc giữa khung nhìn và mô hình khung nhìn. Mục tiêu ở đây là loại bỏ logic trong chế độ xem.
Giống như Chế độ xem, Mô hình phải khá nhẹ và chỉ được sử dụng để truy cập thông tin (dữ liệu) cần thiết cho mô hình chế độ hoạt động. Mô hình có thể kết hợp quyền truy cập vào các nguồn dữ liệu khác nhau, nhưng nó không nên có logic nghiệp vụ. Trong hầu hết các trường hợp, bạn có một kho dữ liệu duy nhất để nhấn. Trong một số trường hợp bạn không. Khi bạn không sử dụng Mô hình để che khuất nguồn dữ liệu từ VM.

Một điểm tiềm ẩn của MVVM là dữ liệu đã được lưu trữ và dự án của bạn không chịu trách nhiệm duy trì tổ chức của nó. Một số dự án đủ may mắn để thoát khỏi giả định đó, hầu hết các dự án tôi từng làm đều không may mắn như vậy. Chỉ cần nói rằng Dữ liệu là một lớp khác mà chúng ta sẽ phải đối mặt.

Tôi sẽ đặt ra dự án của tôi như thế này:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

và lớp này có thể được thêm vào khi cần thiết:

 project.Helpers

Tôi đang tách Người trợ giúp khỏi phần còn lại của ngăn xếp để nó không bị nhầm lẫn là một lớp trong ngăn xếp ứng dụng của bạn.

Tuyên bố miễn trừ trách nhiệm: Tôi không phải là chuyên gia DDD, nhưng tôi hiểu ý chính chung và thấy giá trị trong cách tiếp cận.

Tên miền của bạn sẽ là vấn đề mà bạn đang xem xét.
Các Mô hình Miền sẽ tương ứng chủ yếu với ViewModels mà bạn tạo; một chút trong Lượt xem; và một đoạn nhỏ trong Model / DataStructs.

Vì vậy, làm thế nào là đi làm?
NẾU bạn có khả năng thay đổi cấu trúc dữ liệu hiện có, thì cấu trúc dữ liệu mới mà bạn tạo sẽ tương quan với vấn đề bạn đang cố gắng giải quyết. Có một đối tượng khách hàng? Sau đó, bạn nên có một / một số bảng liên quan đến Khách hàng. Có hóa đơn hay sản phẩm? Câu chuyện tương tự - các bảng và cấu trúc ánh xạ tới các đối tượng kinh doanh đó sẽ được tạo.

Tên miền sẽ được thể hiện thông qua các đối tượng ViewModel của bạn và Chế độ xem mà bạn trình bày về các đối tượng đó. Nếu bạn cần chỉnh sửa hồ sơ khách hàng thì bạn sẽ có VM để xử lý tác vụ đó.

Về câu hỏi của bạn:

  1. Đừng cố chồng DDD lên MVVM. Nó sẽ không hoạt động. DDD không phải là một mẫu bố cục, đó là một cách tiếp cận để xem vấn đề tổng thể của bạn.
  2. Kho lưu trữ và ánh xạ sẽ sống trong cả hai dự án.Data hoặc project.Model nếu thích hợp.
  3. Không có lớp được gọi là UI trừ khi đó là những gì bạn muốn gọi project.Views.
  4. Logic nghiệp vụ sẽ đi vào Mô hình xem.

1
Được rồi, một số, có thể không biết gì, theo dõi câu hỏi. (1) bạn sẽ tạo cho mỗi dự án một dự án riêng biệt hay chỉ các thư mục (ví dụ: Project.View, v.v.)? (2) DataStructs là nơi bạn sẽ đặt * .dbml's hoặc Project.Data? (3) Vì vậy, theo bạn, tôi sẽ không có Project.Domain? Tôi đã thấy rằng sử dụng một vài lần là lý do tại sao tôi hỏi.
Khúc xạ Paladin

@RefractedPaladin - 1) chỉ các thư mục trong dự án. Bạn có thể đưa ra một lập luận rằng Dữ liệu nên là dự án của riêng nó. Từ quan điểm bảo trì, một trong hai cách là tương đương. 2) có, chính xác. 3) không, tôi sẽ không có thư mục .Domain. IMO, công việc của chúng tôi là ánh xạ ứng dụng đến miền vấn đề kinh doanh. Vì vậy, tên miền thấm vào tất cả các lớp của dự án.
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.