Saya mencoba untuk memahami cara menerapkan decoupling yang baik antara UI dan model, tapi saya mengalami kesulitan mencari tahu di mana harus membagi garis.
Saya telah melihat Model-View-Presenter, tapi saya tidak yakin bagaimana cara mengimplementasikannya. Misalnya, Tampilan saya memiliki beberapa dialog ..
- Haruskah ada kelas tampilan dengan instance dari masing-masing dialog? Lalu dalam hal itu, bagaimana seharusnya dialog berinteraksi dengan Presenter? yaitu. jika sebuah dialog individual perlu meminta data dari Model melalui Presenter, bagaimana seharusnya dialog mendapatkan referensi ke Presenter? Melalui referensi ke Tampilan yang diberikan padanya selama konstruksi?
- Saya berpikir mungkin pandangan harus kelas statis? Kemudian dialog GetView dan dapatkan Presenter dari sana ...
- Saya telah berpikir tentang pengaturan Presenter dengan kepemilikan View dan Model (sebagai lawan dari View memiliki Presenter dan Presenter memiliki Model) dan Presenter mendaftarkan panggilan balik untuk acara di View, tetapi itu membuatnya tampak banyak. lebih berpasangan (atau bahasa tergantung, setidaknya.)
Saya mencoba untuk:
- buat ini sebagai dipisahkan mungkin
- idealnya memungkinkan untuk memasangkan Presenter / Model dengan Tampilan dari bahasa lain (Saya belum melakukan banyak hal antar-bahasa, tapi saya tahu itu mungkin, terutama semakin
void(void)
saya bisa bertahan, setidaknya aplikasi C # dengan Pustaka C ++ - menjaga kode tetap bersih dan sederhana
Jadi .. ada saran bagaimana interaksi harus ditangani?
design-patterns
ui
interfaces
coba tangkap
sumber
sumber
Jawaban:
Selamat datang di lereng yang licin. Anda pada titik ini menyadari bahwa ada variasi tanpa akhir dari semua interaksi model-view. MVC, MVP (Taligent, Dolphin, Passive View), MVVM hanya untuk beberapa nama.
Pola Presenter Model View, seperti kebanyakan pola arsitektur terbuka untuk banyak variasi dan eksperimen. Satu hal yang sama dari semua variasi adalah peran presenter sebagai "perantara" antara tampilan dan model. Dua yang paling umum adalah Tampilan Pasif dan Presenter / Pengawas Pembimbing - [ Fowler ]. Tampilan Pasif memperlakukan UI sebagai antarmuka yang sangat dangkal antara pengguna dan presenter. Ini mengandung sangat sedikit jika ada logika, mendelegasikan banyak tanggung jawab kepada presenter. Mengawasi Presenter / Pengendalimencoba mengambil keuntungan dari pengikatan data yang dibangun dalam banyak kerangka UI. UI menangani sinkronisasi data tetapi langkah presenter / controller untuk logika yang lebih kompleks. Dalam kedua kasus model, tampilan dan penyaji membentuk triad
Ada banyak cara untuk melakukan ini. Sangat umum untuk melihat ini ditangani dengan memperlakukan setiap dialog / form sebagai tampilan yang berbeda. Sering kali ada hubungan 1: 1 antara pandangan dan presenter. Ini bukan aturan yang keras dan cepat. Sangat umum untuk memiliki satu presenter menangani banyak pandangan terkait atau sebaliknya. Itu semua tergantung pada kompleksitas pandangan dan kompleksitas logika bisnis.
Adapun bagaimana pandangan dan penyaji mendapatkan referensi satu sama lain, ini kadang-kadang disebut kabel . Anda memiliki tiga pilihan:
View memegang referensi ke presenter
A form atau dialog yang mengimplementasikan view. Formulir ini memiliki pengendali acara yang melakukan delade ke presenter menggunakan panggilan fungsi langsung:
Karena presenter tidak memiliki referensi ke tampilan, view harus mengirimkan data sebagai argumen. Presenter dapat berkomunikasi kembali ke tampilan dengan menggunakan acara / fungsi panggilan balik yang harus didengarkan oleh view.
Presenter memegang referensi untuk melihat
Dalam skenario tampilan memperlihatkan properti untuk data yang ditampilkan kepada pengguna. Presenter mendengarkan acara dan memanipulasi properti pada tampilan:
Keduanya memegang referensi satu sama lain membentuk ketergantungan sirkuler.
Skenario ini sebenarnya lebih mudah untuk dikerjakan dibandingkan yang lain. Tampilan merespons acara dengan memanggil metode di presenter. Presenter membaca / memodifikasi data dari tampilan melalui properti yang terbuka.
Ada masalah lain yang harus dipertimbangkan dengan pola MVP. Urutan penciptaan, masa hidup objek, di mana pengkabelan berlangsung, komunikasi antara triad MVP tetapi jawaban ini telah berkembang cukup lama.
sumber
Seperti yang dikatakan semua orang, ada puluhan pendapat dan tidak ada satu pun yang benar atau salah. Tanpa masuk ke segudang pola dan hanya berfokus pada MVP inilah beberapa saran untuk implementasi.
Pisahkan mereka. Tampilan harus mengimplementasikan antarmuka yang membentuk ikatan antara tampilan dan presenter. Pandangan menciptakan presenter dan menyuntikkan dirinya ke presenter dan memaparkan metode yang ditawarkan untuk presenter untuk berinteraksi dengan tampilan. Pandangan bertanggung jawab untuk menerapkan metode atau properti ini dengan cara apa pun yang diinginkannya. Secara umum Anda memiliki satu tampilan: satu presenter tetapi dalam beberapa kasus Anda dapat memiliki banyak tampilan: satu presenter (web, wpf, dll.). Kuncinya di sini adalah bahwa presenter tidak mengetahui implementasi UI dan hanya berinteraksi dengan tampilan melalui antarmuka.
Ini sebuah contoh. Pertama kita memiliki kelas tampilan dengan metode sederhana untuk menampilkan pesan kepada pengguna:
Sekarang inilah presenternya. Perhatikan bahwa presenter mengambil IView ke konstruktornya.
Sekarang inilah antarmuka pengguna yang sebenarnya. Ini bisa berupa jendela, dialog, halaman web, dll. Tidak masalah. Perhatikan konstruktor untuk tampilan akan membuat presenter dengan menyuntikkan dirinya ke dalamnya.
Presenter tidak peduli tentang bagaimana view mengimplementasikan metode yang baru saja dilakukannya. Untuk semua presenter tahu, itu bisa menulis ke file log dan bahkan tidak menunjukkannya kepada pengguna.
Bagaimanapun, presenter melakukan beberapa pekerjaan dengan model di bagian belakang dan pada suatu titik ingin memberi tahu pengguna tentang apa yang terjadi. Jadi sekarang kita memiliki metode di suatu tempat di presenter yang memanggil ke tampilan pesan InformUser.
Di sinilah Anda mendapatkan decoupling Anda. Presenter hanya memegang referensi untuk implementasi IView dan tidak terlalu peduli bagaimana itu diterapkan.
Ini juga merupakan implementasi orang miskin karena Anda memiliki referensi ke Presenter dalam tampilan dan objek ditetapkan melalui konstruktor. Dalam solusi yang lebih kuat, Anda mungkin ingin melihat wadah inversi kontrol (IOC) seperti Windsor, Ninject, dll. Yang akan menyelesaikan implementasi IView untuk Anda saat runtime sesuai permintaan dan dengan demikian membuatnya semakin terpisah.
sumber
Saya pikir penting untuk diingat bahwa Pengendali / Presenter adalah tempat di mana tindakan tersebut benar-benar terjadi. Coupling di Controller tidak bisa dihindari karena kebutuhan.
Titik inti Pengontrol adalah agar jika Anda membuat perubahan pada Tampilan, maka Model tidak harus berubah dan sebaliknya (jika Model mengubah Tampilan tidak harus salah satu) karena Controller adalah apa yang menerjemahkan Model menjadi View dan kembali lagi. Tetapi Controller akan berubah ketika Model atau View berubah karena Anda harus secara efektif menerjemahkan dalam Controller bagaimana Model untuk Dilihat bagaimana mendapatkan perubahan yang dibuat dalam View kembali ke Mode.
Contoh terbaik yang bisa saya berikan adalah bahwa ketika saya menulis aplikasi MVC, saya tidak hanya dapat memiliki data dalam tampilan GUI, tetapi saya juga dapat menulis rutin yang mendorong data ditarik dari Model ke dalam
string
untuk ditampilkan di debugger (dan dengan ekstensi ke file teks biasa). Jika saya dapat mengambil data Model dan menerjemahkannya secara bebas ke dalam teks tanpa mengubah View atau Model dan hanya Controller, maka saya berada di jalur yang benar.Yang sedang berkata, Anda harus memiliki referensi antara komponen yang berbeda untuk membuat semuanya berfungsi. Controller perlu tahu tentang View untuk mendorong data, View perlu tahu tentang Controller untuk memberi tahu ketika ada perubahan (seperti ketika Pengguna mengklik "Simpan" atau "Baru ..."). Pengendali perlu tahu tentang Model untuk menarik data, tetapi saya berpendapat bahwa Model tidak harus tahu tentang hal lain.
Peringatan: Saya berasal dari latar belakang Cocoa yang benar-benar Mac, Objective-C, yang benar-benar mendorong Anda ke dalam paradigma MVC baik Anda mau atau tidak.
sumber
Secara umum, Anda ingin model Anda merangkum semua interaksi dengan model itu. Misalnya, tindakan CRUD Anda (Buat, Baca, Perbarui, Hapus) semua adalah bagian dari model. Hal yang sama berlaku untuk perhitungan khusus. Ada beberapa alasan bagus untuk ini:
Di controller (aplikasi MVC) Anda, yang Anda lakukan hanyalah mengumpulkan model yang perlu Anda gunakan dalam tampilan Anda, dan memanggil fungsi yang sesuai pada model. Setiap perubahan pada kondisi model terjadi di lapisan ini.
Tampilan Anda hanya menampilkan model yang Anda siapkan. Pada dasarnya, tampilan hanya membaca model dan menyesuaikan outputnya.
Memetakan prinsip umum ke kelas aktual
Ingat bahwa dialog Anda adalah tampilan. Jika Anda sudah memiliki kelas dialog, tidak ada alasan untuk membuat kelas "Tampilan" lainnya. Lapisan Presenter pada dasarnya mengikat model ke kontrol di View. Logika bisnis dan semua data penting disimpan dalam model.
sumber