MVC (Model, View, Controller) adalah pola untuk mengatur kode dalam aplikasi untuk meningkatkan rawatan.
Bayangkan seorang fotografer dengan kameranya di studio. Seorang pelanggan memintanya untuk mengambil foto sebuah kotak.
Arsitektur non-MVC cenderung terintegrasi dengan erat. Jika kotak, pengontrol, dan kamera adalah objek satu-dan-sama-maka, kita harus memisahkan dan kemudian membangun kembali baik kotak dan kamera setiap kali kita ingin mendapatkan tampilan baru. Juga, mengambil foto akan selalu seperti mencoba mengambil foto selfie - dan itu tidak selalu sangat mudah.
bwaha menulis:
Penulis merujuk ke mvctree.py di wxPython sebagai contoh desain MVC. Namun saya masih terlalu hijau sehingga saya menemukan contoh khusus itu terlalu kompleks dan saya tidak memahami pemisahan yang direkomendasikan oleh penulis.
MVC adalah tentang pemisahan masalah.
Model bertanggung jawab untuk mengelola data program (baik data pribadi maupun klien). View / Controller bertanggung jawab untuk menyediakan sarana bagi dunia luar untuk berinteraksi dengan data klien program.
Model menyediakan antarmuka internal (API) untuk mengaktifkan bagian lain dari program untuk berinteraksi dengannya. View / Controller menyediakan antarmuka eksternal (GUI / CLI / formulir web / IPC tingkat tinggi / dll.) Untuk memungkinkan semuanya melebihi program untuk berkomunikasi dengannya.
Model bertanggung jawab untuk menjaga integritas data program, karena jika itu rusak maka itu akan berakhir untuk semua orang. View / Controller bertanggung jawab untuk menjaga integritas UI, memastikan semua tampilan teks menampilkan nilai terbaru, menonaktifkan item menu yang tidak berlaku untuk fokus saat ini, dll.
Model tidak mengandung kode View / Controller; tidak ada kelas widget GUI, tidak ada kode untuk meletakkan kotak dialog atau menerima input pengguna. View / Controller tidak mengandung kode Model; tidak ada kode untuk memvalidasi URL atau melakukan kueri SQL, dan juga tidak ada status asli: setiap data yang dipegang oleh widget hanya untuk tujuan tampilan, dan hanya refleksi dari data sebenarnya yang disimpan dalam Model.
Sekarang, inilah tes dari desain MVC sejati: program pada dasarnya harus berfungsi penuh bahkan tanpa View / Controller terpasang. OK, dunia luar akan mengalami kesulitan berinteraksi dengan itu dalam bentuk itu, tetapi selama orang tahu mantra Model API yang sesuai, program akan menyimpan dan memanipulasi data seperti biasa.
Mengapa ini mungkin? Yah, jawaban sederhananya adalah itu semua berkat kopling rendah antara Model dan lapisan View / Controller. Namun, ini bukan cerita lengkapnya. Apa kunci untuk seluruh pola MVC adalah arah di mana koneksi tersebut berjalan: SEMUA instruksi mengalir dari View / Controller ke Model. Model TIDAK PERNAH memberi tahu View / Controller apa yang harus dilakukan.
Mengapa? Karena di MVC, sementara View / Controller diizinkan untuk mengetahui sedikit tentang Model (khususnya, API Model), tetapi Model tidak diizinkan untuk mengetahui apa pun tentang View / Controller.
Mengapa? Karena MVC adalah tentang menciptakan pemisahan keprihatinan yang jelas.
Mengapa? Untuk membantu mencegah kompleksitas program tidak terkendali dan mengubur Anda, pengembang, di bawahnya. Semakin besar program, semakin besar jumlah komponen dalam program itu. Dan semakin banyak koneksi yang ada di antara komponen-komponen itu, semakin sulit bagi pengembang untuk mempertahankan / memperluas / mengganti komponen individual, atau bahkan hanya mengikuti cara kerja seluruh sistem. Tanyakan kepada diri Anda sendiri: ketika melihat diagram struktur program, apakah Anda lebih suka melihat pohon atau tempat lahir kucing? Pola MVC menghindari yang terakhir dengan melarang koneksi melingkar: B dapat terhubung ke A, tetapi A tidak dapat terhubung ke B. Dalam hal ini, A adalah Model dan B adalah View / Controller.
BTW, jika Anda tajam, Anda akan melihat masalah dengan pembatasan 'satu arah' yang baru saja dijelaskan: bagaimana Model dapat menginformasikan View / Controller perubahan dalam data pengguna Model ketika Model bahkan tidak diizinkan untuk tahu bahwa View / Controller, apalagi mengirim pesan ke sana? Tapi jangan khawatir: ada solusi untuk ini, dan itu agak rapi bahkan jika itu tampak agak bundar pada awalnya. Kami akan kembali ke sana sebentar lagi.
Jadi, secara praktis, objek View / Controller dapat, melalui API Model, 1. memberi tahu Model untuk melakukan sesuatu (mengeksekusi perintah), dan 2. memberi tahu Model untuk memberikan sesuatu (mengembalikan data). Lapisan View / Controller
mendorong instruksi ke lapisan Model dan menarik informasi dari lapisan Model.
Dan di situlah contoh MyCoolListControl pertama Anda salah, karena API untuk kelas itu mengharuskan informasi didorong
ke dalamnya, jadi Anda kembali memiliki penggandaan dua arah di antara lapisan, melanggar aturan MVC dan membuang Anda kembali ke dalam Arsitektur cradle kucing yang Anda [mungkin] coba hindari di tempat pertama.
Sebagai gantinya, kelas MyCoolListControl harus mengikuti arus, menarik data yang dibutuhkan dari lapisan di bawah, saat dibutuhkan. Dalam kasus widget daftar, itu umumnya berarti menanyakan berapa banyak nilai yang ada dan kemudian meminta masing-masing item tersebut pada gilirannya, karena itu tentang cara paling sederhana dan paling longgar untuk melakukannya dan oleh karena itu menjaga agar penggandaan ada minimum. Dan jika widget ingin, katakanlah, untuk menyajikan nilai-nilai itu kepada pengguna dalam urutan abjad yang bagus maka itu adalah perogatifnya; dan tanggung jawabnya, tentu saja.
Sekarang, satu teka-teki terakhir, seperti yang saya sebutkan sebelumnya: bagaimana Anda menjaga tampilan UI disinkronkan dengan keadaan Model dalam sistem berbasis MVC?
Inilah masalahnya: banyak objek Tampilan stateful, misalnya kotak centang mungkin dicentang atau tidak dipilih, bidang teks mungkin berisi beberapa teks yang dapat diedit. Namun, MVC menentukan bahwa semua data pengguna disimpan dalam lapisan Model, sehingga setiap data yang disimpan oleh lapisan lain untuk tujuan tampilan (kondisi kotak centang, teks saat ini bidang teks) harus merupakan salinan tambahan dari data Model utama itu. Tetapi jika status Model berubah, salinan Lihat status itu tidak lagi akurat dan perlu diperbarui.
Tapi bagaimana caranya? Pola MVC mencegah Model mendorong salinan baru dari informasi itu ke dalam layer View. Heck, itu bahkan tidak memungkinkan Model untuk mengirim pesan Lihat untuk mengatakan keadaannya telah berubah.
Hampir saja. Oke, lapisan Model tidak diizinkan untuk berbicara langsung ke lapisan lain, karena untuk melakukannya akan memerlukannya tahu sesuatu tentang lapisan-lapisan itu, dan aturan MVC mencegahnya. Namun, jika sebuah pohon tumbang di hutan dan tidak ada yang mendengarnya, apakah itu mengeluarkan suara?
Jawabannya, Anda lihat, adalah untuk mengatur sistem notifikasi, memberikan lapisan Model tempat yang dapat diumumkan kepada siapa pun khususnya bahwa ia baru saja melakukan sesuatu yang menarik. Lapisan lain kemudian dapat memposting pendengar dengan sistem notifikasi untuk mendengarkan pengumuman yang mereka benar-benar tertarik. Lapisan Model tidak perlu tahu apa-apa tentang siapa yang mendengarkan (atau bahkan jika ada orang yang mendengarkan sama sekali!); hanya memposting pengumuman dan kemudian melupakannya. Dan jika ada yang mendengar pengumuman itu dan merasa ingin melakukan sesuatu setelahnya - seperti meminta Model untuk beberapa data baru sehingga dapat memperbarui tampilan di layarnya - sangat bagus. Model hanya mendaftar pemberitahuan apa yang dikirim sebagai bagian dari definisi API-nya; dan apa yang dilakukan orang lain dengan pengetahuan itu terserah mereka.
MVC dipertahankan, dan semua orang senang. Kerangka kerja aplikasi Anda mungkin menyediakan sistem pemberitahuan bawaan, atau Anda dapat menulis sendiri jika tidak (lihat 'pola pengamat').
...
Bagaimanapun, harapan itu membantu. Setelah Anda memahami motivasi di balik MVC, alasan mengapa segala sesuatunya dilakukan dengan cara mereka mulai masuk akal, bahkan ketika - pada pandangan pertama - mereka tampak lebih kompleks daripada yang diperlukan.
Tepuk tangan,
telah