Saya telah menggunakan MVP dan MVC di masa lalu, dan saya lebih suka MVP karena mengontrol aliran eksekusi jauh lebih baik menurut saya.
Saya telah membuat infrastruktur saya (kelas datastore / repositori) dan menggunakannya tanpa masalah saat mengode data sampel, jadi sekarang saya pindah ke GUI dan menyiapkan MVP saya.
Bagian A
Saya telah melihat MVP menggunakan tampilan sebagai titik masuk, yaitu dalam metode view constructor yang menciptakan presenter, yang pada gilirannya menciptakan model, menghubungkan peristiwa yang diperlukan.
Saya juga telah melihat presenter sebagai titik masuk, di mana pandangan, model dan presenter dibuat, presenter ini kemudian diberi tampilan dan objek model dalam konstruktornya untuk menghubungkan peristiwa.
Seperti pada 2, tetapi model tidak diteruskan ke presenter. Sebaliknya model adalah kelas statis di mana metode dipanggil dan respons dikembalikan secara langsung.
Bagian B
Dalam hal menjaga tampilan dan model dalam sinkronisasi saya telah melihat.
Setiap kali nilai dalam tampilan berubah, yaitu
TextChanged
acara di .Net / C #. Ini menembakkanDataChangedEvent
yang dilewatkan ke dalam model, untuk membuatnya tetap sinkron setiap saat. Dan di mana model berubah, yaitu peristiwa latar belakang yang didengarnya, maka tampilan diperbarui melalui ide yang sama untuk memunculkan aDataChangedEvent
. Ketika seorang pengguna ingin melakukan perubahan,SaveEvent
ia akan menyala, meneruskannya ke dalam model untuk melakukan save. Dalam hal ini model meniru data tampilan dan memproses tindakan.Mirip dengan # b1, namun tampilan tidak disinkronkan dengan model setiap saat. Alih-alih ketika pengguna ingin melakukan perubahan,
SaveEvent
dipecat dan presenter mengambil detail terbaru dan meneruskannya ke dalam model. dalam hal ini model tidak tahu tentang data tampilan sampai diminta untuk menindaklanjutinya, dalam hal ini ia melewatkan semua detail yang diperlukan.
Bagian C
Menampilkan objek bisnis dalam tampilan, yaitu objek (MyClass) bukan data primitif (int, dobel)
Tampilan memiliki bidang properti untuk semua datanya yang akan ditampilkan sebagai objek domain / bisnis. Seperti
view.Animals
memaparkanIEnumerable<IAnimal>
properti, meskipun tampilan memprosesnya menjadi Node dalam TreeView. Kemudian untuk hewan yang dipilih itu akan dieksposSelectedAnimal
sebagaiIAnimal
properti.Pandangan tidak memiliki pengetahuan tentang objek domain, itu memperlihatkan properti untuk primitif / framework (.Net / Java) termasuk hanya tipe objek. Dalam hal ini presenter akan melewatkan objek adaptor objek domain, adaptor kemudian akan menerjemahkan objek bisnis yang diberikan ke kontrol yang terlihat pada tampilan. Dalam hal ini adaptor harus memiliki akses ke kontrol aktual pada tampilan, bukan sembarang tampilan sehingga menjadi lebih erat.
Bagian D
Beberapa tampilan digunakan untuk membuat kontrol tunggal. yaitu Anda memiliki tampilan yang kompleks dengan model sederhana seperti menyimpan objek dari berbagai jenis. Anda dapat memiliki sistem menu di samping dengan setiap klik pada item kontrol yang sesuai ditampilkan.
Anda membuat satu tampilan besar, yang berisi semua kontrol individu yang diekspos melalui antarmuka tampilan.
Anda memiliki beberapa tampilan. Anda memiliki satu tampilan untuk menu dan panel kosong. Tampilan ini menciptakan tampilan lain yang diperlukan tetapi tidak menampilkannya (terlihat = salah), tampilan ini juga mengimplementasikan antarmuka untuk setiap tampilan yang dikandungnya (yaitu tampilan anak) sehingga dapat terpapar ke satu presenter. Panel kosong diisi dengan tampilan lain (
Controls.Add(myview)
) dan ((myview.visible = true
). Peristiwa-peristiwa yang diangkat dalam pandangan "anak" ini ditangani oleh pandangan orang tua yang pada gilirannya meneruskan acara tersebut kepada presenter, dan sebaliknya visa untuk memasok acara kembali ke elemen anak.Setiap tampilan, baik itu tampilan induk utama atau anak kecil masing-masing ditransfer ke sana sendiri presenter dan model. Anda benar-benar dapat menjatuhkan kontrol tampilan ke bentuk yang sudah ada dan itu akan memiliki fungsionalitas siap, hanya perlu kabel ke presenter di belakang layar.
Bagian E
Jika semuanya memiliki antarmuka, sekarang berdasarkan bagaimana MVP dilakukan dalam contoh di atas akan mempengaruhi jawaban ini karena mereka mungkin tidak kompatibel lintas.
Semuanya memiliki antarmuka, View, Presenter, dan Model. Masing-masing ini jelas memiliki implementasi konkret. Bahkan jika Anda hanya memiliki satu tampilan, model, dan presenter yang konkret.
Tampilan dan Model memiliki antarmuka. Ini memungkinkan pandangan dan model berbeda. Presenter membuat / diberi objek tampilan dan model dan itu hanya berfungsi untuk menyampaikan pesan di antara mereka.
Hanya tampilan yang memiliki antarmuka. Model memiliki metode statis dan tidak dibuat, sehingga tidak perlu antarmuka. Jika Anda menginginkan model yang berbeda, presenter memanggil serangkaian metode kelas statis yang berbeda. Menjadi statis, Model tidak memiliki tautan ke presenter.
Pikiran pribadi
Dari semua variasi berbeda yang telah saya sajikan (kebanyakan saya mungkin telah menggunakan dalam beberapa bentuk) yang saya yakin ada lebih banyak. Saya lebih suka A3 menjaga logika bisnis dapat digunakan kembali di luar hanya MVP, B2 untuk lebih sedikit duplikasi data dan lebih sedikit peristiwa yang dipecat. C1 untuk tidak menambahkan di kelas lain, tentu saja menempatkan sejumlah kecil logika non unit yang dapat diuji ke dalam tampilan (bagaimana objek domain divisualisasikan) tetapi ini bisa ditinjau kode, atau hanya dilihat dalam aplikasi. Jika logikanya kompleks saya akan setuju untuk kelas adaptor tetapi tidak dalam semua kasus. Untuk bagian D, saya merasa D1 menciptakan tampilan yang terlalu besar setidaknya untuk contoh menu. Saya telah menggunakan D2 dan D3 sebelumnya. Masalah dengan D2 adalah Anda akhirnya harus menulis banyak kode untuk merutekan acara ke dan dari presenter ke tampilan anak yang benar, dan itu tidak kompatibel dengan drag / drop, setiap kontrol baru perlu lebih banyak kabel untuk mendukung presenter tunggal. D3 adalah pilihan saya yang lebih disukai tetapi menambahkan lebih banyak kelas sebagai presenter dan model untuk menangani tampilan, bahkan jika tampilan sangat sederhana atau tidak perlu digunakan kembali. Saya pikir campuran D2 dan D3 terbaik berdasarkan keadaan. Mengenai bagian E, saya pikir semua yang memiliki antarmuka bisa berlebihan saya sudah melakukannya untuk domain / objek bisnis dan sering melihat tidak ada keuntungan dalam "desain" dengan melakukannya, tetapi itu membantu dalam mengejek objek dalam pengujian. Secara pribadi saya akan melihat E2 sebagai solusi klasik, meskipun telah melihat E3 digunakan dalam 2 proyek yang telah saya kerjakan sebelumnya. Saya pikir campuran D2 dan D3 terbaik berdasarkan keadaan. Mengenai bagian E, saya pikir semua yang memiliki antarmuka bisa berlebihan saya sudah melakukannya untuk domain / objek bisnis dan sering melihat tidak ada keuntungan dalam "desain" dengan melakukannya, tetapi itu membantu dalam mengejek objek dalam pengujian. Secara pribadi saya akan melihat E2 sebagai solusi klasik, meskipun telah melihat E3 digunakan dalam 2 proyek yang telah saya kerjakan sebelumnya. Saya pikir campuran D2 dan D3 terbaik berdasarkan keadaan. Mengenai bagian E, saya pikir semua yang memiliki antarmuka bisa berlebihan saya sudah melakukannya untuk domain / objek bisnis dan sering melihat tidak ada keuntungan dalam "desain" dengan melakukannya, tetapi itu membantu dalam mengejek objek dalam pengujian. Secara pribadi saya akan melihat E2 sebagai solusi klasik, meskipun telah melihat E3 digunakan dalam 2 proyek yang telah saya kerjakan sebelumnya.
Pertanyaan
Apakah saya menerapkan MVP dengan benar? Apakah ada cara yang benar untuk melakukannya?
Saya telah membaca karya Martin Fowler yang memiliki variasi, dan saya ingat ketika saya pertama kali mulai melakukan MVC, saya mengerti konsepnya, tetapi pada awalnya tidak bisa mengetahui di mana titik masuknya, semuanya memiliki fungsi sendiri tetapi apa yang mengontrol dan menciptakan yang asli mengatur objek MVC.
sumber
Jawaban:
Banyak hal yang Anda presentasikan di sini sangat masuk akal dan sehat. Beberapa pilihan akan bergantung pada spesifik dengan aplikasi dan mana yang "terasa" benar. Seperti halnya sebagian besar waktu, tidak akan ada satu jawaban yang benar. Beberapa pilihan akan masuk akal di sini dan pilihan itu bisa sepenuhnya salah untuk aplikasi dan keadaan selanjutnya. Tanpa mengetahui beberapa hal spesifik dari aplikasi ini, saya pikir Anda berada di jalur yang benar dan telah membuat beberapa keputusan yang masuk akal.
Bagi saya, saya merasa bahwa Presenter hampir selalu menjadi titik masuk. Memiliki UI sebagai titik masuknya menempatkan terlalu banyak logika di UI dan menghilangkan kemampuan untuk mengganti UI baru tanpa perubahan kode besar. Dan memang itu pekerjaan presenter.
sumber
Kami menggunakan bentuk MVP yang dimodifikasi pada aplikasi .NET 2.0 Winforms kami. Dua bagian yang kami lewatkan adalah adaptor yang dimodifikasi dari WPF ViewModel, dan menambahkan pengikatan data. Pola spesifik kami adalah MVPVM.
Kami terhubung sebagai penyaji-pertama dalam hampir setiap kasus, kecuali untuk kontrol-kontrol pengguna khusus, yang terhubung terlebih dahulu-untuk kenyamanan perancang. Kami menggunakan injeksi dependensi, ViewModels yang dihasilkan kode, BDD untuk presenter, dan TDD / TED untuk model.
VM hanyalah sebuah properti yang besar dan datar yang meningkatkan PropertyChanged ketika diubah. Sangat mudah untuk menghasilkan ini dengan kode (dan tes unit latihan terkait). Kami menggunakannya untuk membaca dan menulis ke kontrol yang dapat berinteraksi dengan pengguna, dan mengendalikan status yang diaktifkan. ViewModel digabungkan dengan View, karena kami menggunakan penyatuan data untuk hampir semua hal lain.
View kadang-kadang akan memiliki metode untuk mencapai hal-hal yang VM tidak bisa. Ini biasanya mengontrol visibilitas item (WinForms bisa pilih-pilih tentang hal itu), dan hal-hal yang menolak untuk dijadikan databound. Tampilan selalu memperlihatkan peristiwa seperti "Login" atau "Restart", dengan EventArgs yang sesuai untuk bertindak pada perilaku pengguna. Kecuali jika kami harus menggunakan retasan seperti "View.ShowLoginBox", View sepenuhnya dapat dipertukarkan selama memenuhi persyaratan desain umum.
Kami membutuhkan sekitar 6-8 bulan untuk menemukan pola ini. Ini memiliki banyak potongan, tetapi sangat fleksibel dan sangat kuat. Implementasi spesifik kami sangat asinkron dan berdasarkan-peristiwa, yang mungkin hanya merupakan artifak dari persyaratan lain daripada efek samping dari perilaku desain. Sebagai contoh, saya menambahkan sinkronisasi utas ke baseclass dari mana VM kami mewarisi (yang hanya mengekspos metode OnPropertyChanged untuk meningkatkan peristiwa) - dan puf, sekarang kita dapat memiliki presenter dan model multithreaded.
sumber
Saya menggunakan versi PureMvc yang telah dimodifikasi untuk .Net, dan kemudian diperluas sendiri.
Saya sudah terbiasa dengan PureMvc dari menggunakannya di aplikasi Flex. Ini adalah jenis kerangka tulang sehingga cukup mudah untuk beradaptasi jika Anda ingin menyesuaikannya.
Saya mengambil kebebasan berikut ini:
Di PureMvc, Anda bisa menggunakan Perintah untuk menjadi titik masuk, perintah Mulai yang khas akan mengatur Model sejauh mungkin, lalu buat MainForm, buat dan daftarkan mediator untuk dan dengan formulir itu, lalu lakukan Application.Run pada formulir.
Mediator untuk formulir akan bertanggung jawab untuk mengatur semua sub-mediator, beberapa di antaranya dapat diotomatisasi dengan, sekali lagi, menggunakan trik refleksi.
Sistem yang saya gunakan kompatibel dengan drag / drop, jika saya mengerti maksud Anda. Bentuk aktual semua dibuat dalam VS, tetapi pengalaman saya hanya dengan bentuk yang memiliki kontrol yang dibuat secara statis. Hal-hal seperti item menu yang dibuat secara dinamis tampaknya layak dengan sedikit penyesuaian mediator untuk menu atau submenu itu. Di mana itu akan menjadi berbulu adalah ketika mediator tidak memiliki elemen root statis untuk dihubungkan dan Anda masuk ke dalam menciptakan mediator 'instance' yang dinamis.
sumber