Saya seorang pengembang C ++ yang telah menggunakan pola MVC untuk merancang GUI sejak saat itu.
Baru-baru ini saya ingin kembali ke C #, dan saya mengatur aplikasi Windows Forms, tetapi sekarang saya sedikit bingung tentang bagaimana mendorongnya ke struktur yang sesuai dengan MVC.
Apa yang saya coba lakukan saat ini adalah "mendeklarasikan" kelas yang saya berikan untuk WinForms sebagai Tampilan, dan menambahkan kelas untuk Model dan Pengontrol di latar belakang. Namun, saya tidak begitu yakin tentang cara berinteraksi dengan acara, seperti klik tombol. Biasanya saya akan mengarahkan peristiwa ini ke controller, dan melakukan aksi pada View setelah saya selesai.
Ini terasa sangat tidak memuaskan di rasi bintang ini. Misalnya, jika saya ingin menerapkan tombol "Keluar", saya harus mengalihkan acara dari Tampilan ke Pengontrol, serta menerapkan metode publik tambahan dalam Tampilan saya yang kemudian dapat dipanggil dari Pengontrol, sementara saya bisa dengan mudah memanggil Tutup () dari Tampilan pada contoh pertama.
Apakah Anda punya saran untuk saya? Apakah pemahaman saya tentang Formulir Windows di C # hanya belum cukup baik untuk mencoba implementasi MVC? Apakah saya memberi kelas bentuk peran yang salah? Apakah MVC hanyalah arsitektur yang tidak pantas untuk kasus penggunaan ini?
Jawaban:
Secara kebetulan, saya sedang mengerjakan proyek WinForms yang berpola setelah MVC. Saya tidak akan menyebut ini jawaban yang sempurna, tetapi saya akan menjelaskan desain saya secara keseluruhan dan mudah-mudahan ini dapat membantu Anda membuat sendiri.
Berdasarkan bacaan yang saya lakukan sebelum memulai proyek ini, tampaknya tidak ada cara "benar" untuk mengimplementasikan ini. Saya mengikuti prinsip-prinsip desain OOP dan MVC sederhana dan sisanya adalah trial and error ketika saya mengembangkan alur kerja.
Tidak ..? Tidak ada konteks yang cukup dalam pertanyaan Anda untuk memberikan jawaban langsung untuk itu. Mengapa Anda menggunakan MVC? Apa persyaratan tidak fungsional dari proyek Anda? Apakah proyek Anda akan menjadi sangat berat UI? Apakah Anda lebih peduli dengan keamanan dan lebih memilih arsitektur berlapis? Apa komponen utama dari proyek Anda? Mungkin setiap komponen membutuhkan pola desain yang berbeda. Cari tahu mengapa Anda ingin menggunakan pola desain ini di tempat pertama dan Anda mungkin menjawab pertanyaan Anda sendiri;)
Alasan saya menggunakan MVC: ini adalah pola desain yang cukup sederhana untuk dipahami menurut pendapat saya dan desain saya sangat bergantung pada interaksi pengguna. Cara MVC memungkinkan pengembang untuk memisahkan masalah sudah cukup untuk aplikasi saya juga. Ini membuat kode saya jauh lebih mudah dikelola dan diuji.
Saya juga mengira saya menggunakan lebih dari desain hybrid. Biasanya, konsep ideal yang disajikan dalam rekayasa perangkat lunak sebenarnya tidak berlaku dalam praktik. Anda dapat memodifikasi desain sesuai dengan kebutuhan proyek Anda. Tidak perlu terjebak dalam apa yang benar atau salah. Ada praktik umum, tetapi aturan selalu bisa ditekuk atau dilanggar asalkan Anda tidak menembak kaki sendiri.
Implementasi saya dimulai dengan desain tingkat tinggi yang memberi saya ide tentang komponen apa yang akan saya butuhkan. Yang terbaik untuk memulai dengan cara ini dan bekerja dengan cara Anda dalam arsitektur. Berikut adalah diagram paket untuk proyek (dibuat dalam StarUML):
Perhatikan setiap layer kecuali layer presentasi tergantung pada Sistem Pesan. Ini adalah "bahasa" umum yang digunakan lapisan bawah dan sub sistem lapisan tersebut untuk berkomunikasi satu sama lain. Dalam kasus saya, itu adalah penghitungan sederhana berdasarkan operasi yang dapat dilakukan. Yang membawa saya ke poin berikutnya ...
Pikirkan operasi atau perintah sebagai dasar untuk implementasi Anda. Apa yang ingin aplikasi Anda lakukan? Hancurkan menjadi operasi yang paling mendasar. Misalnya: CreateProject, WriteNotes, SaveProject, LoadProject dll. GUI (atau kelas Form) akan memiliki beberapa peristiwa terjadi (seperti tombol tekan). Setiap operasi memiliki metode pengontrol yang terkait dengannya. Dalam hal ini sesuatu seperti Keluar terlalu sederhana. Aplikasi dapat ditutup dari kelas Form. Tapi bagaimana kalau saya ingin menyimpan beberapa data aplikasi ke file terlebih dahulu? Saya akan memanggil metode "Simpan" dari kelas pengontrol masing-masing dalam metode tekan tombol saya.
Dari sana, pengontrol akan memanggil set operasi yang benar dari kelas Layanan. Kelas layanan dalam aplikasi saya bertindak sebagai antarmuka ke lapisan domain. Mereka akan memvalidasi input yang diterima dari panggilan metode pengontrol (dan dengan demikian dari GUI) dan memanipulasi model data.
Setelah validasi dan manipulasi objek yang sesuai selesai, metode layanan akan mengembalikan kode pesan ke controller. Sebagai contoh
MessageCodes.SaveSuccess
,. Baik kelas pengontrol dan layanan didasarkan pada objek domain dan / atau rangkaian operasi umum yang dapat dikelompokkan bersama.Misalnya:
FileMenuController
(operasi: NewProject, SaveProject, LoadProject) ->ProjectServices
(CreateProject, PersistProjectToFile, LoadProjectFromFile). Di manaProject
akan menjadi kelas domain dalam model data Anda. Kelas Controller dan Service dalam kasus saya adalah kelas yang tidak dapat instantiable dengan metode statis.Kemudian, pengontrol mengenali operasi sebagai penyelesaian tidak berhasil. Sekarang, controller memiliki sistem pesan sendiri yang digunakannya untuk berinteraksi dengan lapisan presentasi, karenanya ketergantungan ganda antara lapisan Layanan dan Presentasi. Dalam hal ini kelas yang dipanggil
ViewState
dalamViewModels
paket selalu dikembalikan ke GUI oleh controller. Keadaan ini berisi informasi seperti: "Apakah negara tempat Anda mencoba membuat aplikasi itu valid? ", " Pesan yang dapat dibaca manusia tentang operasi yang Anda coba lakukan dan mengapa itu berhasil atau tidak berhasil (pesan kesalahan) " dan sebuahViewModel
kelas.The
ViewModel
kelas berisi data yang relevan dari lapisan domain bahwa GUI akan digunakan untuk memperbarui tampilan. Model tampilan ini terlihat seperti kelas domain tetapi dalam kasus saya, saya menggunakan objek yang sangat kurus . Pada dasarnya mereka hampir tidak memiliki perilaku, hanya menyampaikan informasi tentang tingkat aplikasi yang lebih rendah. Dengan kata lain, saya TIDAK PERNAH akan memberikan kelas domain saya ke lapisan presentasi. Ini juga mengapa paketControllers
danServices
membagi lapisan layanan menjadi dua bagian. Pengontrol tidak akan pernah menangani kelas domain atau memvalidasi negara mereka. Mereka hanya bertindak sebagai batas mengkonversi data yang relevan GUI menjadi data yang relevan dengan domain yang dapat digunakan layanan dan sebaliknya. Termasuk logika servis di controller akan menyebabkan sangat gemuk pengendali, yang sulit dipertahankan.Saya harap ini memberi Anda titik awal.
sumber