Saya pikir terminologi yang digunakan dalam Qt dengan kontrol model / tampilan cacat. Pada halaman penjelasan mereka menyatakan, bahwa mereka menyederhanakan MVC menjadi MV dengan menggabungkan View dan Controller dan mereka memberikan gambar sebagai berikut:
Namun menurut saya, mereka salah menamai peran objek dan saya pikir,
- Apa yang mereka sebut Tampilan dengan Pengontrol gabungan sebenarnya adalah Tampilan saja.
- Apa yang mereka sebut Model sebenarnya hanyalah Pengendali.
- Jika Anda benar-benar ingin memiliki model, itu akan berada di suatu tempat di mana "Data" mereka berada.
Saya berbicara tentang cara biasa dan waras Anda akan menggunakan komponen model / tampilan Qt di aplikasi Anda. Berikut alasannya:
- Ini biasanya merupakan komponen Qt yang digunakan apa adanya, tanpa menambahkan logika Pengontrol khusus untuk objek Anda)
- Ini bukan Model, hanya karena Anda harus mengimplementasikan beberapa metode Qt seperti rowCount, columnCount, data, dll. Yang tidak ada hubungannya dengan model Anda. Sebenarnya ada metode model khas yang ditemukan di Pengontrol. Tentu saja, Anda dapat mengimplementasikan logika Controller dan Model di sini, tetapi pertama-tama ini akan menjadi desain kode yang buruk dan kedua Anda akan menggabungkan Controller dan Model bukan Controller dan View seperti yang dinyatakan.
- Seperti yang dikatakan dalam alasan 2. jika Anda ingin memisahkan logika Model yang tentunya bukan kotak biru pada gambar, melainkan kotak "Data" yang putus-putus (tentu saja berkomunikasi dengan Data nyata).
Apakah Qt salah dalam terminologi mereka, atau hanya saya yang tidak mengerti? (BTW: Alasan mengapa ini bukan pertanyaan akademis adalah karena saya sudah mulai membuat kode proyek saya mengikuti penamaan mereka dan saya segera menemukan, bahwa kode itu jelas tidak benar. Baru setelah itu saya menyadari, saya harus tidak mencoba menempatkan logika Model dalam apa yang mereka sebut Model)
Jawaban:
Saya setuju dengan Anda bahwa penamaan Qt menyesatkan. Namun menurut saya, masalahnya bukan hanya pada Qt, tetapi juga dimiliki oleh semua kerangka kerja yang memungkinkan kita untuk mematuhi prinsip pemisahan masalah saat menerapkan UI kami. Ketika seseorang datang dengan kerangka kerja seperti itu, dan menemukan cara yang baik untuk memisahkan "hal-hal", mereka selalu merasa berkewajiban untuk memiliki modul yang mereka sebut "Model" dan modul lain yang mereka sebut "Tampilan". Selama bertahun-tahun saya telah bekerja dengan kerangka kerja ini:
Jika Anda membandingkan bagaimana istilah "Model" dan "Tampilan" digunakan dalam kerangka kerja ini, dan tanggung jawab apa yang dimiliki kelas dalam "Tampilan", "Model", dan "Pengontrol" (jika ada), Anda akan menemukan bahwa terdapat perbedaan yang sangat besar. Tentu akan berguna untuk memiliki perbandingan konsep dan terminologi yang berbeda, sehingga orang-orang yang beralih dari satu kerangka ke kerangka lainnya memiliki kesempatan untuk tetap waras, tetapi itu akan membutuhkan banyak pekerjaan dan penelitian. Bacaan yang bagus adalah milik Martin Fowler gambaran umum .
Karena ada begitu banyak ide-ide yang berbeda apa yang pola MVC dapat terlihat seperti, mana yang benar? Menurut pendapat saya, orang-orang yang menemukan MVC harus berpaling ketika kita ingin tahu bagaimana seharusnya diimplementasikan dengan "benar". Di kertas smalltalk asli dikatakan:
Oleh karena itu saya akan menjawab tiga perhatian utama Anda sebagai berikut:
Dimana kita ditinggalkan? Menurut pendapat saya, yang terbaik adalah mencari tahu apa sebenarnya yang dimaksud Qt ketika istilah "Model" dan "View" digunakan dan menggunakan istilah tersebut dengan cara mereka saat kita memprogram dengan Qt. Jika Anda terus diganggu, hal itu hanya akan memperlambat Anda, dan cara pengaturan di Qt memungkinkan desain yang elegan - yang lebih berat daripada konvensi penamaan yang "salah".
sumber
Jawaban singkat
MVC Qt hanya berlaku untuk satu struktur data . Saat berbicara tentang aplikasi MVC, Anda tidak boleh memikirkan
QAbstractItemModel
atauQListView
.Jika Anda menginginkan arsitektur MVC untuk seluruh program Anda, Qt tidak memiliki kerangka kerja model / tampilan yang "besar". Tetapi untuk setiap daftar / pohon data dalam program Anda, Anda dapat menggunakan pendekatan Qt MVC yang memang memiliki pengontrol dalam tampilannya. The Data adalah dalam atau di luar model; ini tergantung pada jenis model yang Anda gunakan (model subclass sendiri: mungkin di dalam model; misalnya QSqlTableModel: di luar (tapi mungkin di-cache di dalam) model). Untuk menyatukan model dan tampilan Anda, gunakan kelas sendiri yang kemudian mengimplementasikan logika bisnis .
Jawaban panjang
Pendekatan dan terminologi model / tampilan Qt:
Qt memberikan tampilan sederhana untuk model mereka. Mereka memiliki pengontrol bawaan: memilih, mengedit, dan memindahkan item adalah sesuatu yang dalam banyak kasus "kontrol" pengontrol. Yaitu, menafsirkan input pengguna (klik dan gerakan mouse) dan memberikan perintah yang sesuai ke model.
Model Qt memang model yang memiliki data dasar. Model abstrak tentu saja tidak menyimpan data, karena Qt tidak tahu bagaimana Anda ingin menyimpannya. Tapi Anda memperluas QAbstractItemModel sesuai kebutuhan Anda dengan menambahkan container data ke subclass dan membuat antarmuka model mengakses data Anda. Jadi sebenarnya, dan saya berasumsi Anda tidak menyukai ini, masalahnya adalah Anda perlu memprogram model, jadi bagaimana data diakses dan dimodifikasi dalam struktur data Anda.
Dalam terminologi MVC, model berisi data dan logika . Di Qt, terserah Anda apakah Anda menyertakan beberapa logika bisnis Anda ke dalam model atau meletakkannya di luar, menjadi "tampilan" sendiri. Bahkan tidak jelas apa yang dimaksud dengan logika: Memilih, mengganti nama, dan memindahkan item? => sudah diimplementasikan. Melakukan perhitungan dengan mereka? => Letakkan di luar atau di dalam subclass model. Menyimpan atau memuat data dari / ke file? => Taruh di dalam subclass model.
Pendapat pribadi saya:
Sangat sulit untuk menyediakan sistem MV (C) yang baik dan umum untuk programmer. Karena dalam banyak kasus modelnya sederhana (misalnya hanya daftar string) Qt juga menyediakan QStringListModel yang siap digunakan. Tetapi jika data Anda lebih kompleks daripada string, terserah Anda bagaimana Anda ingin merepresentasikan data melalui antarmuka model / tampilan Qt. Jika Anda memiliki, misalnya, sebuah struct dengan 3 bidang (katakanlah orang dengan nama, usia dan jenis kelamin) Anda dapat menetapkan 3 bidang ke 3 kolom berbeda atau ke 3 peran berbeda. Saya tidak menyukai kedua pendekatan tersebut.
Saya pikir kerangka model / tampilan Qt hanya berguna ketika Anda ingin menampilkan struktur data sederhana . Ini menjadi sulit untuk ditangani jika data memiliki tipe khusus atau tidak terstruktur dalam pohon atau daftar (misalnya grafik). Dalam kebanyakan kasus, daftar sudah cukup dan bahkan dalam beberapa kasus, model hanya boleh menampung satu entri tunggal. Terutama jika Anda ingin memodelkan satu entri tunggal yang memiliki atribut berbeda (satu contoh dari satu kelas), kerangka kerja model / tampilan Qt bukanlah cara yang tepat untuk memisahkan logika dari antarmuka pengguna.
Singkatnya, saya pikir kerangka kerja model / tampilan Qt berguna jika dan hanya jika data Anda dilihat oleh salah satu widget penampil Qt . Sama sekali tidak berguna jika Anda akan menulis penampil Anda sendiri untuk model yang hanya berisi satu entri, misalnya pengaturan aplikasi Anda, atau jika data Anda bukan jenis yang dapat dicetak.
Bagaimana saya menggunakan model / tampilan Qt dalam aplikasi (lebih besar)?
Saya pernah menulis (dalam tim) sebuah aplikasi yang menggunakan beberapa model Qt untuk mengelola data. Kami memutuskan untuk membuat
DataRole
untuk menyimpan data aktual yang memiliki tipe kustom berbeda untuk setiap subclass model yang berbeda. Kami membuat kelas model luar yang disebutModel
memegang semua model Qt yang berbeda. Kami juga membuat kelas tampilan luar yang disebutView
menahan jendela (widget) yang terhubung ke model di dalamnyaModel
. Jadi pendekatan ini adalah Qt MVC yang diperluas, disesuaikan dengan kebutuhan kita sendiri. BaikModel
danView
kelas itu sendiri tidak ada hubungannya dengan Qt MVC.Dimana kita meletakkan logikanya ? Kami membuat kelas yang melakukan penghitungan aktual pada data dengan membaca data dari model sumber (saat model berubah) dan menulis hasilnya ke dalam model target. Dari sudut pandang Qt, kelas logika ini akan menjadi pandangan, karena mereka "terhubung" ke model (bukan "tampilan" untuk pengguna, tetapi "tampilan" untuk bagian logika bisnis aplikasi).
Dimana pengontrolnya ? Dalam terminologi MVC asli, pengontrol menafsirkan input pengguna (mouse dan keyboard) dan memberikan perintah ke model untuk melakukan tindakan yang diminta. Karena tampilan Qt sudah menafsirkan input pengguna seperti mengganti nama dan memindahkan item, ini tidak diperlukan. Tetapi yang kami butuhkan adalah interpretasi dari interaksi pengguna yang melampaui tampilan Qt.
sumber
View
Anda harus menambahkan model proxy, yang memiliki model pohon sebagai model dasarnya dan digunakan oleh tampilan daftar sistem file Anda. Seperti yang Anda katakan: seharusnya tidak ada dua model untuk data yang sama. Tidak pernah! (Tapi model proxy tidak dihitung sebagai model terpisah.)QAbstractItemModel
, beberapa di antaranya adalah model dalam pengertian MVC dan beberapa di antaranya tidak.Istilahnya tidak benar atau salah, itu berguna atau tidak berguna.
Anda mungkin mengubah pertanyaannya sedikit dan bertanya mengapa Qt tidak lebih ramah MVC. Jawabannya adalah bahwa pengembang Qt awal percaya bahwa memisahkan V dari C dalam aplikasi GUI menghasilkan Vs dan C yang buruk keduanya. Desain QWidget mencoba membuatnya sederhana untuk mengikat interperasi input mouse secara dekat dengan keputusan output piksel, dan Anda dapat melihat bagaimana itu bukan jalan menuju MVC.
sumber
Seperti fungsi Model adalah untuk merespon permintaan informasi, saya pikir tidak ada yang salah dalam mendefinisikan metode seperti
rowCount
,columnCount
, dll saya pikir Model adalah beberapa jenis pembungkus untuk sumber data (tidak peduli apa itu SQL meja atau hanya sebuah array) , ini menyediakan data dalam bentuk standar, dan Anda harus menentukan metode bergantung pada struktur sumber data Anda.sumber
Saya yakin terminologi mereka benar ... meskipun dalam aplikasi nyata saya merasa sangat mudah untuk mengaburkan garis antara model, tampilan, dan pengontrol tergantung pada tingkat abstraksi Anda: pandangan satu tingkat mungkin merupakan model tingkat yang lebih tinggi.
Saya merasa kebingungan muncul dari kelas QAbstractModelItem mereka. Kelas ini bukan item model, melainkan antarmuka ke model. Untuk membuat antarmuka kelas tampilan mereka dengan model, mereka harus membuat antarmuka abstrak generik ke model. Namun, model dapat berupa satu item, daftar item, tabel dari 2 atau lebih dimensi item, dll; jadi antarmuka mereka harus mendukung semua variasi model ini. Memang, ini membuat item model cukup kompleks, dan kode perekat untuk membuatnya bekerja dengan model sebenarnya tampaknya sedikit meregangkan metafora.
sumber
Tidak, "model" mereka jelas bukan pengontrol.
Kontroler adalah bagian dari kontrol yang terlihat oleh pengguna yang memodifikasi model (dan karenanya secara tidak langsung mengubah tampilan). Misalnya, tombol "hapus" adalah bagian dari pengontrol.
Saya pikir sering terjadi kebingungan karena banyak yang melihat sesuatu seperti "controller memodifikasi model" dan berpikir ini berarti fungsi yang bermutasi pada model mereka, seperti metode "deleteRow ()". Tetapi di MVC klasik, pengontrol secara khusus adalah bagian antarmuka pengguna. Metode yang mengubah model hanyalah bagian dari model.
Sejak MVC ditemukan, perbedaan antara pengontrol dan tampilan menjadi semakin tegang. Pikirkan tentang kotak teks: ini menampilkan beberapa teks dan memungkinkan Anda mengeditnya, jadi apakah itu tampilan atau pengontrol? Jawabannya haruslah itu adalah bagian dari keduanya. Dulu ketika Anda mengerjakan teletype di tahun 1960-an, perbedaannya lebih jelas - pikirkan
ed
- tetapi itu tidak berarti segalanya lebih baik bagi pengguna saat itu!Memang benar bahwa QAbstractItemModel mereka memiliki level yang lebih tinggi daripada model biasanya. Misalnya, item di dalamnya dapat memiliki warna latar belakang (secara teknis kuas), yang merupakan atribut view-ish yang jelas! Jadi ada argumen bahwa QAbstractItemModel lebih seperti tampilan dan data Anda adalah modelnya. Sebenarnya itu ada di suatu tempat di antara makna klasik dari pandangan dan model. Tapi saya tidak bisa melihat bagaimana itu sebuah pengontrol; jika ada widget QT yang menggunakannya.
sumber