Làm rõ MVVM


14

Chúng tôi sắp viết ứng dụng WPF đầu tiên của mình và làm quen với mẫu MVVM. Chúng tôi đã xây dựng nhiều ứng dụng Winform và có một kiến ​​trúc rất thành công đối với chúng tôi. Chúng tôi gặp một chút khó khăn khi dịch kiến ​​trúc đó hoặc xác định vị trí các phần nhất định của kiến ​​trúc phù hợp với mô hình MVVM.

Trong lịch sử, chúng ta có một Gui (exe chính) sau đó giao tiếp với một dll BusinessLogic. BusinessLogic liên lạc với một dll DAL thông qua dịch vụ web và DAL tương tác với DB. Tất cả DAL, BusinessLogic và GUI đều tham chiếu cùng một dll BusinessObjects.

Kiến trúc AsIs

Một số chuyển đổi sang MVVM khá đơn giản. Gui của chúng tôi vẫn sẽ chứa các khung nhìn, BusinessOjbects của chúng tôi vẫn sẽ chứa mô hình và DAL của chúng tôi vẫn sẽ tương tác với DB (mặc dù công nghệ để thực hiện chúng có thể thay đổi).

Điều chúng tôi không chắc chắn là thành phần BusinessLogic của chúng tôi. Về mặt lịch sử, điều này sẽ cung cấp các hàm cho GUI để gọi các điều khiển trong các khung nhìn (ví dụ: GetCustomerList sẽ trả về danh sách các đối tượng Khách hàng hoặc các hàm CRUD điển hình).

Vấn đề chính chúng ta có là liệu mẫu MVVM sẽ gọi một thành phần bổ sung để chứa ViewModels hay nếu chúng ta chỉ thay đổi suy nghĩ và di chuyển những gì chúng ta đã sử dụng làm thành phần BusinessLogic sang ViewModels?

Thành phần BusinessLogic của chúng tôi có đại diện cho ViewModels không?


Điều này nghe có vẻ giống như một giải pháp tìm kiếm một vấn đề. Có một lý do thuyết phục tại sao bạn chuyển sang MVVM không? Tôi là một fan hâm mộ của mô hình nhưng giải pháp trước đây của bạn không hoạt động? Mô hình xem giống như một người trình bày giám sát. Nó chứa logic trình bày và hiển thị dữ liệu thông qua liên kết dữ liệu. Nó nên biết về logic kinh doanh của bạn và có thể tiếp cận tầng đó, nhưng tôi sẽ không thu gọn logic kinh doanh vào chính mô hình xem.
Jeremy Likness

Câu trả lời:


18

Nói chung, tôi sẽ không đặt logic kinh doanh trong lớp mô hình xem. Nhưng thuật ngữ "Logic kinh doanh" là sai lệch.

Eric Evans sử dụng một mô hình trong đó logic kinh doanh được chia thành hai loại

  • Logic miền - Logic liên quan đến miền vấn đề thực tế bạn đang giải quyết
  • Logic ứng dụng - Logic liên quan đến thực tế, rằng bạn đang xây dựng một ứng dụng

Ông đề cập đến ví dụ về một ứng dụng kế toán. Quy tắc về tài khoản, bài đăng, tài khoản thuế, v.v. là quy tắc tên miền, quy tắc liên quan đến lĩnh vực kế toán. Logic về nhập / xuất CSV không liên quan gì đến lĩnh vực kế toán. Các quy tắc này tồn tại hoàn toàn vì chúng tôi đang xây dựng một ứng dụng phần mềm. Đây là những ví dụ về logic ứng dụng.

Các quy tắc miền KHÔNG BAO GIỜ nên đi vào lớp mô hình xem. Nếu bạn đang theo mẫu MVVM, thì các quy tắc miền sẽ đi, không có câu hỏi, trong lớp mô hình.

Quy tắc ứng dụng, như nhập / xuất CSV, có thể đi vào lớp mô hình xem. Nhưng cá nhân, tôi thích tách nó ra thành một lớp logic ứng dụng riêng biệt.

Mô hình xem nên rất đơn giản. Tra cứu dữ liệu cần thiết cho chế độ xem trong mô hình tương ứng, cập nhật mô hình khi chế độ xem thay đổi, lắng nghe các sự kiện trong mô hình và truyền các sự kiện đó đến chế độ xem, cho phép chế độ xem được cập nhật khi mô hình được cập nhật phía sau hậu trường (nếu có).

Cá nhân tôi sẽ đảm bảo rằng lớp mô hình khung nhìn chỉ chứa một loại logic, logic trình bày.


1
Câu trả lời tuyệt vời. Tôi thích điểm đảm bảo ViewModel chỉ chứa logic Trình bày. Bạn có thể thêm bất kỳ liên kết liên quan đến điểm Eric Evans của bạn?
dùng7676

Tôi nghi ngờ tôi có thể tìm thấy một liên kết, bởi vì tôi tin rằng tôi đã nhận được nó từ cuốn sách của ông, Thiết kế hướng tên miền. Dù sao, tôi nghĩ đó là một ví dụ tuyệt vời về sự khác biệt giữa logic miền và ứng dụng. Thêm thông tin về cuốn sách ở đây Books.google.dk/books/about/ Kẻ
Pete

5

Đúng.

Lớp logic nghiệp vụ được biểu diễn bằng lớp VM. Vì vậy, chỉ cần di chuyển mô hình tinh thần của bạn.

Để giúp di chuyển mô hình tinh thần của bạn, một sắc thái nhỏ là các đối tượng GUI (Chế độ xem) phải được liên kết với các đối tượng trong lớp VM. Sự ràng buộc đó chuyển thành | ngụ ý rằng Chế độ xem không còn là lớp "thực hiện cuộc gọi" để truy xuất nội dung khác. Thay vào đó, cuộc gọi để lấy dữ liệu sẽ đến từ VM.

Để giải thích rõ hơn: Có, một đối tượng trong Chế độ xem sẽ cần thay đổi để kích hoạt chuỗi các thứ sẽ thực hiện cuộc gọi. Nhưng View không thực hiện cuộc gọi. Và trong trường hợp này, tôi coi một lần bấm nút là tương đương với một cái gì đó trong Chế độ xem thay đổi, nhưng vẫn không thực hiện cuộc gọi.

Trong trường hợp đầu tiên, đối tượng View đó sẽ được liên kết với một đối tượng VM. VM nên lắng nghe một sự kiện thay đổi thuộc tính trên đối tượng bị ràng buộc. Sự kiện thay đổi đối tượng sau đó có thể được nối với một chức năng VM để thực hiện cuộc gọi Model.

Trong trường hợp thứ hai (sự kiện nhấn nút), sự kiện thay đổi (nhấp chuột) có thể được nối với một cuộc gọi chức năng được VM phơi bày.

Dù bằng cách nào, đó luôn là một sự kiện nối tiếp vào VM mà sau đó gọi Mô hình mà lần lượt gọi là DAL / DB.

Tôi đưa nó lên bởi vì một số mã WinForm được sử dụng để thực hiện cuộc gọi đến lớp DB trực tiếp từ mã phía sau của GUI WinForm. Cách tiếp cận đó phá vỡ sự tách biệt mà MVVM đang cung cấp.


Cám ơn vì đã xác nhận. Chúng tôi hiểu sắc thái của cách View tương tác với ViewModel và sẽ giữ nguyên mô hình liên kết và bỏ "cuộc gọi".
dùng7676

Tôi nhận thấy rằng câu trả lời này đã mất một phiếu bầu lên. Tôi tò mò nếu downvoter sẽ bình luận tại sao? Hoặc có thể thêm câu trả lời của riêng họ nếu họ không chia sẻ quan điểm này.
dùng7676

1
Tôi đồng ý rằng lớp logic nghiệp vụ được biểu thị bằng lớp VM, tuy nhiên tôi nghĩ các phần trong câu trả lời của bạn có thể gây nhầm lẫn. Các Viewlớp được hiểu là một đại diện trực quan của ViewModel hoặc mẫu, vì vậy thay vì nói sự kiện nhấn là dây vào một cuộc gọi chức năng trên VM, một định nghĩa tốt hơn là nên nói Bộ chỉ huy trong VM được kết xuất như một nút trong lớp View. Ngoài ra, tôi thường không thích lớp Model của mình có thể truy cập trực tiếp vào DAL, vì vậy luồng ứng dụng của tôi thường sẽ đi VM -> DAL -> DB, trong đó VMDALcả hai đều sử dụng các Modelđối tượng dữ liệu đơn giản .
Rachel

4
Tôi không đồng ý với câu trả lời này. ViewModel là mô hình của khung nhìn, nó chứa logic xem chứ không phải logic nghiệp vụ. ViewModels là một phần của lớp trình bày
simoraman

1
@simoraman - Mẫu MVPVM phù hợp với những gì bạn đề xuất. Tôi nghĩ MVPVM là một mô hình tốt, nhưng hơi nặng đối với các ứng dụng nhỏ hơn. Tôi thực sự sẽ khuyến khích bạn đặt suy nghĩ của bạn vào một câu trả lời và đóng góp cho câu hỏi này.

5

Bạn đúng là về cơ bản bạn sẽ thay thế dll BusinessLogic của bạn bằng lớp ViewModel của bạn, tuy nhiên tôi nghĩ rằng sự khác biệt lớn nhất mà bạn sẽ phải đối mặt là cách lớp View / UI tương tác với lớp ViewModel / BusinessLogic của bạn.

Trong WinForms, GUI là ứng dụng của bạn và chịu trách nhiệm về luồng ứng dụng. Trong WPF / MVVM, ViewModels là ứng dụng của bạn và GUI trở thành giao diện thân thiện với người dùng để tương tác với ViewModels.

Ví dụ: với WinForms, bạn có thể có DataGrid và Nút và khi bạn nhấp vào nút đó, bạn gọi BusinessLogicLayer.GetProducts() và tải các đối tượng Sản phẩm kết quả vào DataGrid.

Với WPF, bạn sẽ có một ViewModel chứa một ObservableCollection<Products>và mộtICommand GetProducts , và thực thi lệnh gọi DAL và tải bộ sưu tập các sản phẩm. Nhưng để cung cấp giao diện thân thiện với người dùng cho điều này, bạn sẽ tạo Chế độ xem hiển thị ViewModel của bạn bằng DataGrid cho bộ sưu tập Sản phẩm và Nút cho lệnh Get Products.

Tôi thực sự đã viết một bài đăng gần đây cho blog của mình về sự thay đổi trong suy nghĩ khi chuyển từ Winforms sang WPF trên blog của tôi và tôi nghĩ cách tốt nhất để tóm tắt sự khác biệt là với những bức ảnh này:


1
Tôi đồng ý với GlenH7, đây là một câu trả lời tốt cho ai đó bắt đầu với WPF. Chúng tôi nhận được sự thay đổi mô hình của sự tương tác giữa View và ViewModel vì vậy đây không thực sự là chủ đề cho câu hỏi tôi đã hỏi.
dùng7676
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.