Làm cách nào để thiết lập MVP cho giải pháp Winforms?


14

Tôi đã sử dụng MVP và MVC trong quá khứ và tôi thích MVP hơn vì nó kiểm soát luồng thực thi tốt hơn theo quan điểm của tôi.

Tôi đã tạo cơ sở hạ tầng của mình (kho dữ liệu / lớp kho lưu trữ) và sử dụng chúng mà không gặp vấn đề gì khi mã hóa dữ liệu mẫu cứng, vì vậy bây giờ tôi đang chuyển sang GUI và chuẩn bị MVP của mình.

Mục A

  1. Tôi đã thấy MVP sử dụng khung nhìn làm điểm vào, đó là trong phương thức xây dựng khung nhìn, nó tạo ra người trình bày, từ đó tạo ra mô hình, nối các sự kiện khi cần.

  2. Tôi cũng đã xem người trình bày là điểm vào, trong đó một khung nhìn, mô hình và người trình bày được tạo ra, người trình bày này sau đó được đưa ra một khung nhìn và đối tượng mô hình trong hàm tạo của nó để kết nối các sự kiện.

  3. Như trong 2, nhưng mô hình không được chuyển cho người trình bày. Thay vào đó, mô hình là một lớp tĩnh nơi các phương thức được gọi và các phản hồi được trả về trực tiếp.

Mục B

Về mặt giữ quan điểm và mô hình đồng bộ tôi đã thấy.

  1. Bất cứ khi nào một giá trị trong chế độ xem thay đổi, tức là TextChangedsự kiện trong .Net / C #. Điều này kích hoạt một DataChangedEventcái được truyền qua mô hình, để giữ cho nó đồng bộ mọi lúc. Và khi mô hình thay đổi, tức là một sự kiện nền mà nó lắng nghe, thì khung nhìn được cập nhật thông qua cùng một ý tưởng nâng cao a DataChangedEvent. Khi người dùng muốn cam kết thay đổi, SaveEventnó sẽ kích hoạt, chuyển qua mô hình để thực hiện lưu. Trong trường hợp này, mô hình bắt chước dữ liệu của chế độ xem và xử lý các hành động.

  2. Tương tự như # b1, tuy nhiên, chế độ xem không đồng bộ hóa với mô hình mọi lúc. Thay vào đó khi người dùng muốn thực hiện các thay đổi, SaveEventsẽ bị sa thải và người trình bày nắm bắt các chi tiết mới nhất và chuyển chúng vào mô hình. trong trường hợp này, mô hình không biết về dữ liệu khung nhìn cho đến khi bắt buộc phải hành động theo nó, trong trường hợp đó, nó được chuyển qua tất cả các chi tiết cần thiết.

Mục C

Hiển thị các đối tượng kinh doanh trong dạng xem, tức là một đối tượng (MyClass) không phải dữ liệu nguyên thủy (int, double)

  1. Khung nhìn có các trường thuộc tính cho tất cả dữ liệu của nó mà nó sẽ hiển thị dưới dạng các đối tượng miền / doanh nghiệp. Chẳng hạn như view.Animalshiển thị một thuộc IEnumerable<IAnimal>tính, mặc dù chế độ xem xử lý các thuộc tính này thành các Nút trong TreeView. Sau đó, đối với động vật được chọn, nó sẽ phơi bày SelectedAnimalnhư IAnimaltài sản.

  2. Khung nhìn không có kiến ​​thức về các đối tượng miền, nó chỉ hiển thị thuộc tính cho các kiểu đối tượng nguyên thủy / khung (.Net / Java). Trong trường hợp này, người trình bày sẽ truyền một đối tượng bộ điều hợp cho đối tượng miền, bộ điều hợp sau đó sẽ dịch một đối tượng kinh doanh nhất định thành các điều khiển hiển thị trên khung nhìn. Trong trường hợp này, bộ điều hợp phải có quyền truy cập vào các điều khiển thực tế trên chế độ xem, không chỉ bất kỳ chế độ xem nào trở nên gắn kết chặt chẽ hơn.

Mục D

Nhiều khung nhìn được sử dụng để tạo một điều khiển duy nhất. tức là Bạn có một chế độ xem phức tạp với một mô hình đơn giản như lưu các đối tượng thuộc các loại khác nhau. Bạn có thể có một hệ thống menu ở bên cạnh với mỗi lần nhấp vào một mục, các điều khiển thích hợp được hiển thị.

  1. Bạn tạo một chế độ xem lớn, chứa tất cả các điều khiển riêng lẻ được hiển thị qua giao diện chế độ xem.

  2. Bạn có nhiều quan điểm. Bạn có một chế độ xem cho menu và bảng điều khiển trống. Chế độ xem này tạo các chế độ xem khác được yêu cầu nhưng không hiển thị chúng (hiển thị = sai), chế độ xem này cũng thực hiện giao diện cho mỗi chế độ xem mà nó chứa (tức là chế độ xem con) để nó có thể hiển thị cho một người thuyết trình. Bảng trống được lấp đầy với các khung nhìn khác ( Controls.Add(myview)) và ( (myview.visible = true). Các sự kiện được nêu trong các cuộc phỏng vấn "trẻ em" này được xử lý theo quan điểm của phụ huynh, từ đó chuyển sự kiện đến người trình bày và ngược lại để cung cấp các sự kiện trở lại cho các yếu tố con.

  3. Mỗi chế độ xem, có thể là chính của phụ huynh hoặc các chế độ xem con nhỏ hơn, mỗi chế độ được kết nối với người trình bày và mô hình riêng. Bạn hoàn toàn có thể thả một điều khiển xem vào một biểu mẫu hiện có và nó sẽ có chức năng sẵn sàng, chỉ cần nối dây vào một người thuyết trình đằng sau hậu trường.

Mục E

Nếu mọi thứ đều có giao diện, bây giờ dựa trên cách MVP được thực hiện trong các ví dụ trên sẽ ảnh hưởng đến câu trả lời này vì chúng có thể không tương thích chéo.

  1. Mọi thứ đều có giao diện, View, Presenter và Model. Mỗi trong số đó rõ ràng có một triển khai cụ thể. Ngay cả khi bạn chỉ có một cái nhìn cụ thể, mô hình và người trình bày.

  2. Khung nhìn và Model có giao diện. Điều này cho phép các quan điểm và mô hình khác nhau. Người trình bày tạo / được đưa ra khung nhìn và các đối tượng mô hình và nó chỉ phục vụ để truyền các thông điệp giữa chúng.

  3. Chỉ có View có giao diện. Mô hình có các phương thức tĩnh và không được tạo, do đó không cần giao diện. Nếu bạn muốn một mô hình khác, người trình bày gọi một tập các phương thức lớp tĩnh khác. Là tĩnh Mô hình không có liên kết đến người trình bày.

Suy nghĩ cá nhân

Từ tất cả các biến thể khác nhau mà tôi đã trình bày (hầu hết tôi có thể đã sử dụng ở một số hình thức) mà tôi chắc chắn có nhiều hơn. Tôi thích A3 vì giữ logic kinh doanh có thể tái sử dụng bên ngoài chỉ MVP, B2 để ít trùng lặp dữ liệu và ít sự kiện hơn được thực hiện. C1 vì không thêm vào một lớp khác, chắc chắn rằng nó đặt một lượng nhỏ logic không thể kiểm tra đơn vị vào một khung nhìn (cách một đối tượng miền được trực quan hóa) nhưng điều này có thể được xem xét mã hoặc đơn giản là xem trong ứng dụng. Nếu logic phức tạp, tôi sẽ đồng ý với một lớp bộ điều hợp nhưng không phải trong mọi trường hợp. Đối với phần D, tôi cảm thấy D1 tạo ra một khung nhìn quá lớn cho một ví dụ về menu. Tôi đã sử dụng D2 và D3 trước đây. Vấn đề với D2 là cuối cùng bạn phải viết rất nhiều mã để định tuyến các sự kiện đến và từ người trình bày đến chế độ xem con chính xác và không tương thích kéo / thả, mỗi điều khiển mới cần thêm dây vào để hỗ trợ người trình bày duy nhất. D3 là lựa chọn ưa thích của tôi nhưng thêm vào nhiều lớp hơn là người thuyết trình và người mẫu để xử lý chế độ xem, ngay cả khi chế độ xem xảy ra rất đơn giản hoặc không cần phải sử dụng lại. tôi nghĩ rằng một hỗn hợp của D2 và D3 là tốt nhất dựa trên hoàn cảnh. Đối với phần E, tôi nghĩ mọi thứ có giao diện đều có thể quá mức tôi đã làm điều đó cho các đối tượng miền / doanh nghiệp và thường không thấy lợi thế nào trong "thiết kế" bằng cách làm như vậy, nhưng nó giúp ích trong việc thử nghiệm các đối tượng trong các thử nghiệm. Cá nhân tôi sẽ thấy E2 là một giải pháp cổ điển, mặc dù đã thấy E3 được sử dụng trong 2 dự án tôi đã làm việc trước đây. tôi nghĩ rằng một hỗn hợp của D2 và D3 là tốt nhất dựa trên hoàn cảnh. Đối với phần E, tôi nghĩ mọi thứ có giao diện đều có thể quá mức tôi đã làm điều đó cho các đối tượng miền / doanh nghiệp và thường không thấy lợi thế nào trong "thiết kế" bằng cách làm như vậy, nhưng nó giúp ích trong việc thử nghiệm các đối tượng trong các thử nghiệm. Cá nhân tôi sẽ thấy E2 là một giải pháp cổ điển, mặc dù đã thấy E3 được sử dụng trong 2 dự án tôi đã làm việc trước đây. tôi nghĩ rằng một hỗn hợp của D2 và D3 là tốt nhất dựa trên hoàn cảnh. Đối với phần E, tôi nghĩ mọi thứ có giao diện đều có thể quá mức tôi đã làm điều đó cho các đối tượng miền / doanh nghiệp và thường không thấy lợi thế nào trong "thiết kế" bằng cách làm như vậy, nhưng nó giúp ích trong việc thử nghiệm các đối tượng trong các thử nghiệm. Cá nhân tôi sẽ thấy E2 là một giải pháp cổ điển, mặc dù đã thấy E3 được sử dụng trong 2 dự án tôi đã làm việc trước đây.

Câu hỏi

Tôi có thực hiện MVP chính xác không? Có một cách đúng đắn về nó?

Tôi đã đọc tác phẩm của Martin Fowler có các biến thể và tôi nhớ khi tôi mới bắt đầu làm MVC, tôi đã hiểu khái niệm này, nhưng ban đầu không thể biết đâu là điểm vào, mọi thứ đều có chức năng riêng nhưng điều khiển và tạo bản gốc tập hợp các đối tượng MVC.


2
Lý do để hỏi câu hỏi này là tôi đang tìm cách làm cho nó đúng trong gần như lần thử đầu tiên. Tôi thà có một MVP tiêu chuẩn để theo dõi, thay vì tạo 6 ứng dụng bằng các biến thể khác nhau cho cùng một mẫu.
JonWillis

Hoàn hảo ... Tôi muốn hỏi nó từ lâu
The King

Câu trả lời:


4

Rất nhiều những gì bạn trình bày ở đây là rất hợp lý và âm thanh. Một số lựa chọn sẽ phụ thuộc vào chi tiết cụ thể với ứng dụng và lựa chọn nào "cảm thấy" đúng. Như trường hợp hầu hết thời gian, sẽ không có một câu trả lời đúng. Một số lựa chọn sẽ có ý nghĩa ở đây và những lựa chọn đó có thể hoàn toàn sai cho ứng dụng và hoàn cảnh tiếp theo. Không biết một số chi tiết cụ thể của ứng dụng, tôi nghĩ rằng bạn đang đi đúng hướng và đã đưa ra một số quyết định đúng đắn, chu đáo.

Đối với tôi, tôi cảm thấy rằng Người thuyết trình hầu như luôn luôn là điểm vào. Có UI làm điểm vào đặt quá nhiều logic trong UI và lấy đi khả năng thay thế UI mới mà không cần thay đổi mã hóa lớn. Và thực sự đó là công việc của người trình bày.


Có lẽ câu hỏi tôi nên hỏi là bất kỳ cách nào để sử dụng MVP hoàn toàn sai. Tôi đồng ý với các biến thể phù hợp với các kịch bản khác nhau, nhưng cảm thấy nên có một cách tiếp cận thường được chấp nhận. Các ví dụ về MVP đều là các ví dụ đơn giản và gần như tất cả đều có cùng nhu cầu, để chỉnh sửa một đối tượng miền và lưu các thay đổi. Tuy nhiên, từ những ví dụ có cùng mục tiêu, các biến thể trên đã được tạo ra. Tôi vừa mã hóa một phần của ứng dụng bằng cách sử dụng các sự kiện được kích hoạt trong chế độ xem để được xử lý trong người trình bày nhưng tôi có thể có chế độ xem giữ tham chiếu đến người trình bày và gọi trực tiếp các phương thức.
JonWillis

Tôi đồng ý với tất cả nỗ lực nhằm đơn giản hóa quan điểm để biện minh cho việc nó không phải là đơn vị được thử nghiệm, sau đó người trình bày nên có quyền kiểm soát. Mối quan tâm duy nhất của tôi với điều này (suy nghĩ trong đầu tôi có thể sai) là nói winforms / usercontrols có thể cần được liên kết với các phần tử cha mẹ và tự hỏi liệu có cần thêm logic trong người thuyết trình để viết nó không.
JonWillis

@Jon - Cách MVP sai? Trong cuốn sách của tôi sẽ là khi quan điểm biết về người trình bày. Nó có thể không "sai" theo nghĩa là nó hoạt động nhưng nó sẽ không phải là MVP, nó biến thành một thứ khác vào thời điểm đó. Vấn đề với các mẫu thiết kế là các ví dụ luôn sạch sẽ và đơn giản nhất có thể. Sau đó, khi bạn đi thực hiện chúng lần đầu tiên và thế giới thực nhảy lên và nói 'các ứng dụng thực sự phức tạp hơn nhiều so với ví dụ trừng phạt đó'. Đó là nơi tăng trưởng của bạn bắt đầu. Tìm những gì làm việc cho bạn và hoàn cảnh của ứng dụng.
Walter

Cảm ơn vì lời khuyên. Tôi nhớ học MVC ở trường đại học. Nghe có vẻ tuyệt vời nhưng với một khung vẽ trống, bạn tự hỏi nên bắt đầu từ đâu và làm thế nào nó thực sự hoạt động. Về mặt MVP bị sai, ý tôi là bất kỳ ý tưởng / phương sai nào của MVC tôi đã đăng ở trên cách làm sai, tức là khi khung nhìn biết cách người trình bày làm việc. Hoặc chế độ xem có tham chiếu đến giao diện của người trình bày hoặc loại cụ thể, v.v. Chỉ cần nhiều biến thể khác nhau có thể hoạt động cho cùng một mục đích.
JonWillis

1
@Jon - Các biến thể của bạn đều khá phù hợp với tinh thần của MVP. Theo như làm việc với các giao diện hoặc các loại cụ thể, nó sẽ phụ thuộc vào hoàn cảnh của ứng dụng. Nếu ứng dụng khá nhỏ, không phức tạp lắm thì có lẽ việc thêm giao diện là không cần thiết. Tôi muốn giữ mọi thứ đơn giản nhất có thể, cho đến khi khá rõ ràng rằng ứng dụng hoàn toàn cần thực hiện kiến ​​trúc X. Xem câu trả lời này để biết thêm chi tiết: lập trình
Walter

4

Chúng tôi sử dụng một hình thức MVP đã sửa đổi trên ứng dụng .NET 2.0 Winforms của chúng tôi. Hai phần chúng tôi đã thiếu là một bộ điều hợp đã sửa đổi của WPF ViewModel và thêm ràng buộc dữ liệu. Mẫu cụ thể của chúng tôi là MVPVM.

Chúng tôi kết nối với tư cách là người thuyết trình trước tiên trong hầu hết mọi trường hợp, ngoại trừ các điều khiển người dùng tùy chỉnh, được nối dây trước tiên cho sự thân thiện của nhà thiết kế. Chúng tôi sử dụng phép nội xạ phụ thuộc, ViewModels được tạo mã, BDD cho người thuyết trình và TDD / TED cho mô hình.

Các VM chỉ là một khối lớn, bằng phẳng, các thuộc tính nâng cao PropertyChanged khi chúng được thay đổi. Rất dễ dàng để tạo ra chúng bằng mã (và các bài kiểm tra đơn vị thực hiện liên quan của chúng). Chúng tôi sử dụng chúng để đọc và ghi vào các điều khiển tương tác với người dùng và kiểm soát các trạng thái được kích hoạt. ViewModel được kết hợp với View, vì chúng tôi sử dụng cơ sở dữ liệu cho việc chết tiệt gần mọi thứ khác.

Chế độ xem đôi khi sẽ có các phương thức trên đó để thực hiện những điều mà VM không thể. Điều này thường kiểm soát khả năng hiển thị của các mục (WinForms có thể kén chọn về nó) và những thứ từ chối là cơ sở dữ liệu. Chế độ xem luôn hiển thị các sự kiện như "Đăng nhập" hoặc "Khởi động lại", với EventArss phù hợp để hành động theo hành vi của người dùng. Trừ khi chúng tôi phải sử dụng một bản hack như "View.ShowLoginBox", thì View hoàn toàn có thể hoán đổi cho nhau miễn là nó đáp ứng các yêu cầu thiết kế chung.

Chúng tôi mất khoảng 6-8 tháng để vẽ ra mô hình này. Nó có rất nhiều mảnh, nhưng rất linh hoạt và vô cùng mạnh mẽ. Việc triển khai cụ thể của chúng tôi rất không đồng bộ và theo hướng sự kiện, có thể chỉ là một tạo tác của các yêu cầu khác chứ không phải là tác dụng phụ của hành vi thiết kế. Chẳng hạn, tôi đã thêm đồng bộ hóa luồng vào lớp cơ sở mà máy ảo của chúng tôi kế thừa (đơn giản chỉ hiển thị một phương thức OnPropertyChanged để nâng cao sự kiện) - và bây giờ chúng ta có thể có các trình bày và mô hình đa luồng.


Tôi biết MVPVM của bạn có thể được quan tâm về mặt thương mại, nhưng nếu ổn, bạn có thể cung cấp bất kỳ mã mẫu nào không? Bên cạnh đó, bạn vẽ đường thẳng trên những gì làm trong mô hình và những gì diễn ra trong người trình bày. Tôi đã thấy người thuyết trình rất cơ bản, họ xử lý các sự kiện xem và chỉ cần gọi mô hình, đến người thuyết trình truy cập các lớp dữ liệu để truyền các đối tượng kinh doanh cho một mô hình, cho đến khi mô hình được thay thế bởi người trình bày.
JonWillis

Đúng, hãy để tôi hoàn thành một ví dụ. Nó sẽ được điều chỉnh một chút theo hướng kinh doanh của chúng tôi, vì tôi đang sử dụng nó như một công cụ đào tạo nội bộ.
Bryan Boettcher

Cảm ơn bạn, tôi sẽ xem qua nó vào cuối tuần để xem tôi có hiểu không
JonWillis

@insta - liên kết bị hỏng, bạn có thể tải lại ở đâu đó không?
Yves Schelpe

1
Crap tôi vừa xóa nó như một tuần trước. Số liệu :(
Bryan Boettcher

2

Tôi đang sử dụng phiên bản PureMvc đã được sửa đổi cho .Net và sau đó tự mở rộng.

Tôi đã quen với PureMvc khi sử dụng nó trong các ứng dụng Flex. Đây là một loại khung xương trần nên khá dễ thích ứng nếu bạn muốn tùy chỉnh nó.

Tôi đã có những tự do sau đây với nó:

  • Sử dụng sự phản chiếu, tôi có thể có được các thuộc tính riêng tư trong trình hòa giải khung nhìn để đi vào lớp biểu mẫu và lấy tham chiếu (riêng tư) cho mỗi điều khiển mà tôi đang làm trung gian.
  • Sử dụng sự phản chiếu Tôi có thể tự động kết nối các điều khiển với các chữ ký sự kiện trong bộ trung gian hòa giải của mình, là chung chung, vì vậy tôi chỉ cần bật tham số người gửi.
  • Thông thường, PureMvc muốn các bộ trung gian dẫn xuất xác định sở thích thông báo của chúng trong một hàm sẽ trả về một chuỗi các chuỗi. Vì sở thích của tôi chủ yếu là tĩnh và tôi muốn có một cách dễ dàng hơn để xem lợi ích của hòa giải viên, tôi đã sửa đổi để hòa giải viên cũng có thể khai báo sở thích của mình bằng cách đặt các biến thành viên bằng một chữ ký cụ thể: _ _ _ <classname> _ <tên thông báo>. Bằng cách này tôi có thể thấy những gì đang diễn ra bằng cách sử dụng cây thành viên IDE thay vì nhìn vào bên trong một hàm.

Trong PureMvc, bạn có thể sử dụng Lệnh để làm điểm vào, lệnh Bắt đầu thông thường sẽ thiết lập Mô hình theo mức độ có thể, sau đó tạo MainForm, tạo và đăng ký hòa giải cho và với biểu mẫu đó, sau đó thực hiện Application.Run về hình thức.

Hòa giải cho mẫu sẽ chịu trách nhiệm thiết lập tất cả các hòa giải viên phụ, một số điều này có thể được tự động hóa bằng cách sử dụng các thủ thuật phản xạ.

Hệ thống tôi đang sử dụng tương thích kéo / thả, nếu tôi hiểu ý nghĩa của bạn. Tất cả các biểu mẫu thực tế được tạo trong VS, nhưng trải nghiệm của tôi chỉ với các biểu mẫu có các điều khiển được tạo tĩnh. Những thứ như các mục menu được tạo động có vẻ khả thi với một chút tinh chỉnh của bộ trung gian cho menu hoặc menu con đó. Nơi mà nó sẽ có lông là khi hòa giải viên không có phần tử gốc tĩnh nào được nối vào và bạn đã tạo ra các trung gian 'thể hiện' động.

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.