Dalam arsitektur MVC, seberapa dekat digabungkan Model dan Tampilan ke Controller?


16

Saya punya aplikasi yang menggunakan MVC, tapi saya sedikit kesulitan tentang bagaimana controller harus dirancang. Sebagai contoh, View hanya melihat beberapa bagian dari data model sekaligus. Namun, saya tidak yakin bagaimana tepatnya ini harus diatur. Apakah normal untuk Tampilan atau Model untuk langsung memanggil fungsi pada Controller, misalnya? Melalui semacam antarmuka? Atau apakah mereka benar-benar dikemas dan tidak pernah tahu tentang Controller atau satu sama lain?

Sama seperti hasil edit; ini adalah aplikasi khusus yang tidak ditulis dalam kerangka web apa pun, jadi saya tidak mencari detail kerangka khusus di sini dan memiliki kebebasan untuk membuat pilihan sendiri.


1
Saya tidak akan menjawab karena pengalaman saya terbatas dalam arsitektur MVC, tetapi dari semua yang saya pernah dengar dan bicarakan dengan orang lain, M&V digabungkan secara erat satu sama lain tetapi tidak pada C. M umumnya memanggil fungsi pada C dan V sering hanya databinds ke beberapa subset dari M.
Steven Evers

8
@SnOrfus: Itu persis berlawanan dengan apa yang saya pikir - M & V digabungkan ke C tetapi tidak satu sama lain.
DeadMG

1
Bagaimana bisa begitu banyak jawaban yang salah. Di sini membaca versi MS msdn.microsoft.com/en-us/library/ff649643.aspx
Reactgular

Jawaban:


15

Pengontrol mengontrol aliran aktivitas. Pengguna melakukan tindakan ini, pengontrol meneruskan data tampilan ke domain yang melakukan apa pun yang perlu dilakukan kemudian, berdasarkan pada respons, pengontrol memberi tahu kerangka kerja tampilan mana yang akan ditampilkan berikutnya (dan memberikannya cukup data untuk dilakukan begitu).

Pengontrol demikian harus digabungkan ke model domain, sampai batas tertentu. yaitu. Anda bisa meletakkan lapisan layanan di antara tetapi, dengan definisi yang ketat, itu menjadi bagian dari domain.

Ini juga digabungkan ke data tampilan tetapi bukan tampilan itu sendiri. yaitu. itu hanya mengatakan "tunjukkan tampilan pelanggan menggunakan detail pelanggan ini." Kerangka kerja kemudian memutuskan di mana ia harus menemukan pandangan itu.

Sekarang ini akan memungkinkan Anda untuk memisahkan model domain dari tampilan, dengan menggunakan model tampilan dari data yang sama. Beberapa pengembang melakukan ini, beberapa tidak, dan saya pikir sebagian besar masalah preferensi pribadi.

Di Rails, Anda sangat dianjurkan untuk mendorong objek domain (ActiveRecord) ke tampilan dan percaya bahwa tampilan tidak mengambil keuntungan dari akses itu (mis. Anda tidak boleh menelepon pelanggan. Hemat dari tampilan, meskipun itu akan tersedia).

Di dunia .NET, kita cenderung mengurangi risiko dengan tidak membiarkan hal-hal yang seharusnya tidak terjadi dan, mungkin karena alasan itu, bagi saya tampaknya model tampilan terpisah lebih populer.


1
Lihat model adalah praktik yang sangat umum ketika datang ke unit testing. Anda biasanya akan otomatis memetakan model domain atau objek DTO ke model tampilan. Anda kemudian akan menggunakan model tampilan Anda dalam tampilan. Model tampilan mudah diuji dan tidak terikat ke lapisan di bawah ini.
CodeART

7

Catatan: Robert C. Martin (alias Paman Bob) menjelaskan hal ini dengan cara yang jauh lebih baik dan lucu dalam keynote-nya, Architecture the Lost Years . Agak panjang tapi mengajarkan banyak konsep bagus.

tl; dr: Jangan pikirkan dan rencanakan aplikasi Anda dalam hal MVC. Kerangka kerja MVC hanyalah detail implementasi.

Yang paling membingungkan tentang MVC adalah, pengembang mencoba menggunakan semua komponen yang direkatkan bersama.

Cobalah berpikir dalam kerangka program, bukan kerangka kerja.

Program Anda memiliki tujuan. Dibutuhkan beberapa data, melakukan sesuatu dengan data, dan mengembalikan beberapa data.

Dengan begitu, controllerinilah mekanisme penyampaian program Anda.

  1. Seorang pengguna mengirimkan permintaan ke program Anda (katakanlah, tambahkan produk ke keranjang belanja).
  2. Pengontrol mengambil permintaan itu (info produk dan info pengguna), ia memanggil bagian yang diperlukan dari program Anda yang akan menangani permintaan ini $user->addToCart($product)
  3. Program Anda ( addToCartfungsi userobjek dalam kasus ini) melakukan pekerjaan yang dimaksudkan untuk dilakukan dan mengembalikan respons (katakanlah success)
  4. Pengontrol menyiapkan respons menggunakan yang relevan view: mis. di objek pengontrol$this->render($cartView('success')

Dengan cara ini, pengontrol dipisahkan dari program, dan digunakan sebagai mekanisme pengiriman. Mereka tidak tahu bagaimana program Anda bekerja, mereka hanya tahu bagian mana dari program yang perlu dipanggil untuk permintaan.

Jika Anda ingin menggunakan kerangka kerja lain, aplikasi Anda tidak perlu perubahan, Anda hanya perlu menulis pengontrol yang relevan untuk memanggil program Anda untuk meminta.

Atau jika Anda ingin membuat versi desktop, aplikasi Anda akan tetap sama, Anda hanya perlu menyiapkan mekanisme pengiriman.

Dan itu Model. Anggap saja sebagai mekanisme ketekunan.

Dengan cara OO, ada objek dalam program Anda yang menyimpan data.

class User {
    //...
    private $id;
    private $shoppingCart;
    //...
}

class Product {
    //...
    private $id;
    //...
}

Ketika Anda menambahkan produk ke keranjang belanja, Anda dapat menambahkan product::idke user::shoppingCart.

Dan ketika Anda ingin mempertahankan data, Anda bisa menggunakan modelbagian kerangka kerja, yang umumnya terdiri dari menggunakan ORM, untuk memetakan kelas ke tabel database.

Jika Anda ingin mengubah ORM yang Anda gunakan, program Anda akan tetap sama, hanya informasi pemetaan yang akan berubah. Atau jika Anda ingin menghindari database bersama-sama, Anda bisa menulis data ke file teks biasa, dan aplikasi Anda akan tetap sama.


Jadi, tuliskan program Anda terlebih dahulu. Jika Anda memprogram dengan cara 'OO', gunakan benda-benda bahasa lama yang sederhana. Jangan berpikir dalam hal MVC pada awalnya.


Video yang bagus. Terima kasih. Saya akan tidak setuju dengan interpretasi Anda tentang itu. MVC bukan detail dalam arti bahwa Paman Bob ada di sana. Anda akan mencatat bahwa MVC adalah pola arsitektur seperti pola "Interactor / Entity / Boundary" yang ia bangun. Di sisi lain, sistem MVC tertentu, seperti Spring atau apa pun, memang sesuatu yang dia rekomendasikan untuk ditunda. Saat ia menjelaskan, kerangka kerja ini disebut "MVC" adalah semacam bastardisasi istilah.
Edward Strange

Ya, saya menulis bahwa dengan cara orang berpikir apa MVCitu. Itu sebabnya saya menulis MVC Framework.
Hakan Deryal

2

Martin Fowler melakukan pekerjaan yang baik untuk menggambarkan paradigma MVC. Berikut ini tautan ke artikelnya di sini http://martinfowler.com/eaaDev/uiArchs.html

Perhatikan kutipannya tentang Presentasi Terpisah "Gagasan di balik Presentasi Terpisah adalah untuk membuat pembagian yang jelas antara objek domain yang memodelkan persepsi kita tentang dunia nyata, dan objek presentasi yang merupakan elemen GUI yang kita lihat di layar."


1

Berikut adalah contoh sederhana tentang bagaimana MVC dapat digunakan dalam aplikasi Java Swing yang khas ...

Katakanlah Anda memiliki Panel yang berisi Tombol dan TextField. Ketika Tombol ditekan, suatu peristiwa dipecat, yang mengarah ke beberapa perubahan status dalam aplikasi. Setelah perubahan status terdaftar, TextField menjadi dinonaktifkan.

Ini, kemudian, akan menjadi pendekatan khas yang diambil oleh aplikasi MVC sederhana ...

Pengontrol mendaftarkan dirinya sebagai pendengar acara View. Ketika Tombol diklik, Tampilan itu sendiri tidak menangani acara; Kontroler tidak. Pengontrol adalah Swing khusus karena harus berurusan dengan peristiwa yang terkait dengan Swing.

Pengendali menerima pemberitahuan ini dan harus memutuskan siapa yang harus menanganinya (Tampilan atau Model). Karena peristiwa ini akan mengubah keadaan aplikasi, ia memutuskan untuk meneruskan informasi kepada Model yang bertanggung jawab atas data dan logika program. Beberapa membuat kesalahan dengan menempatkan logika program di Controller tetapi dalam OOP, Model mewakili data DAN perilaku. Baca Martin Fowler tentang hal ini.

Pesan diterima oleh Model dalam konteks yang tepat. Artinya, sama sekali tidak ada referensi untuk Swing atau referensi spesifik GUI lainnya. Pesan ini berbicara kepada Model dan HANYA model. Jika Anda menemukan diri Anda mengimpor pernyataan javax.swing dalam Model, Anda tidak mengkodekan Model dengan benar.

Model kemudian menetapkan statusnya ke 'dinonaktifkan' dan melanjutkan untuk memberi tahu pihak yang berkepentingan tentang perubahan model ini. View, yang tertarik pada acara ini telah mendaftarkan diri sebagai Pengamat perubahan model apa pun. Setelah peristiwa perubahan status Model diambil oleh View, ia melanjutkan untuk menonaktifkan TextField-nya. Juga sah bagi View untuk mendapatkan informasi Read-Only langsung dari Modelnya tanpa harus melalui Controller (biasanya melalui antarmuka spesifik yang diekspos oleh Model untuk aktivitas semacam itu)

Dengan mempromosikan hubungan longgar antara Presentation dan Business Logic dan Layers Data, Anda akan menemukan kode Anda jauh lebih mudah dikelola. Ketika sistem tumbuh, demikian juga pendekatan Anda terhadap MVC. Misalnya, Hierarchical MVC adalah ekstensi yang sering digunakan untuk menghubungkan triad MVC bersama untuk membentuk sistem perusahaan besar tanpa menggabungkan subsistem bersama


0

Kopling (jenis yang ingin Anda hindari) melibatkan saling ketergantungan antara dua kelas. Artinya, Foo tergantung pada Bar dan Bar tergantung pada Foo sehingga Anda tidak dapat benar-benar memodifikasi satu tanpa memodifikasi yang lain. Itu hal yang buruk.

Anda tidak dapat benar-benar menghindari memiliki BEBERAPA dependensi. Kelas harus tahu sedikit tentang satu sama lain, kalau tidak mereka tidak akan pernah berkomunikasi.

Dalam pola MVC, Pengontrol mengontrol komunikasi antara Model domain dan tampilan presentasi. Dengan demikian, Pengendali harus cukup tahu tentang Model untuk memintanya melakukan apa yang seharusnya dilakukan. Pengontrol juga harus cukup tahu tentang Tampilan untuk dapat menyajikannya kepada klien atau pengguna. Jadi, Pengendali Model memiliki dependensi pada keduanya. Namun, View dapat eksis dengan baik tanpa Kontroler - tidak ada ketergantungan di sana. Demikian juga Model tidak memiliki depency pada controller - itu hanya apa adanya. Akhirnya, Model dan Tampilan sepenuhnya terpisah satu sama lain.

Pada dasarnya, Pengendali adalah tingkat tipuan yang memisahkan pandangan dari Model, sehingga mereka tidak perlu tahu tentang satu sama lain.


Ah - itu sebabnya downvotes - saya salah menulis. Maksud saya Controller memiliki ketergantungan pada keduanya. Doh!
Matius Flynn

-5

Dalam pengalaman saya, umumnya model hanya tergantung pada satu pandangan, tidak spesifik satu, sering sebagai pengamat ... jika memiliki kopling seperti sama sekali.

Pandangan umumnya berpasangan dengan apa pun yang dilihatnya, yang masuk akal. Sulit untuk datang dengan tampilan yang dapat dipisahkan dari apa yang dilihatnya ... tetapi kadang-kadang Anda dapat memiliki kopling parsial atau sesuatu.

Kontroler sering cenderung berpasangan dengan keduanya. Ini juga masuk akal karena tugasnya adalah mengubah acara menjadi perubahan model.

Tentu saja, ini hanya kecenderungan yang telah saya amati dan tidak benar-benar mengatakan apa pun tentang contoh spesifik apa pun.

Untuk memahami apa itu MVC dan apa hubungan kopling cenderung, Anda harus melihat bagaimana MVC muncul. Lingkungan tempat MVC dibuat adalah lingkungan di mana "widget" sebagai elemen bentuk yang dapat Anda gunakan untuk membangun dialog tidak ada. "Tampilan" adalah sebuah kotak dan itu menarik banyak hal. Tampilan teks akan menjadi kotak yang akan menggambar teks. Tampilan daftar adalah kotak yang akan menggambar daftar. "Controller" menerima semua acara mouse dan keyboard dari sistem UI yang terjadi dalam tampilan itu; tidak ada acara "textChanged" atau "selectionChanged". Pengontrol akan mengambil semua peristiwa tingkat rendah ini dan menghasilkan interaksi dengan model. Model, setelah diubah akan memberitahukan pandangannya; kami sejak saat itu melihat hubungan ini sebagai "pengamat" dan itu

ITULAH inti dari pola MVC. Karena pemrograman UI tingkat rendah semacam ini umumnya tidak dilakukan lagi, MVC telah berkembang ke berbagai arah. Beberapa hal yang menggunakan nama itu sekarang sama sekali tidak seperti MVC dan harus benar-benar disebut sesuatu yang lain. Itu masih dapat digunakan meskipun dalam arti dialog sebagai keseluruhan berinteraksi dengan objek yang lebih besar. Ada banyak alternatif yang lebih baik.

Pada dasarnya, semua yang dimaksudkan untuk diselesaikan MVC terjadi di dalam widget sekarang dan merupakan sesuatu yang tidak lagi harus kita gunakan.


Bagi mereka yang berpikir mereka lebih tahu:

http://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod

http://msdn.microsoft.com/en-us/library/ff649643.aspx

Saya yakin ada lebih banyak tetapi itu hanya bagian atas daftar di google. Seperti yang Anda lihat, model sangat tergantung pada tampilan antarmuka dalam implementasi BANYAK. Umumnya model dapat diamati dan pandangannya adalah pengamat.

Tapi mengapa membiarkan fakta menghalangi ...

Artikel yang sudah diposting di jawaban lain juga mendukung pernyataan saya:

http://martinfowler.com/eaaDev/uiArchs.html

Jika orang ingin terus mengatakan bahwa SEMUA ORANG dalam industri desain salah maka itu tidak masalah.


4
Ini jelas salah. Model tidak boleh bergantung pada tampilan! Bahkan jika tampilan itu abstrak atau antarmuka. Seorang model harus sepenuhnya dipisahkan dari presentasi!
Falcon

3
Jawabannya salah. Model tidak tergantung pada tampilan atau pengontrol.
CodeART

2
@Crazy Eddie You berkata: "Dalam pengalaman saya, umumnya model hanya bergantung pada tampilan, bukan spesifik, sering sebagai pengamat" Referensi Anda yang dikutip mengatakan: "Namun, model tidak tergantung pada tampilan maupun pengontrol." Pernahkah Anda membaca artikel yang dikutip? Tidak terlihat seperti itu.
CodeART

2
@Crazy Eddie: Saya tidak peduli apa yang ditulis oleh seseorang di codeproject jelek. Ini adalah desain yang mengerikan. Menggunakan pengamat untuk mendengarkan perubahan tidak masalah, tetapi menempatkan antarmuka presentasi dalam model domain adalah hal yang salah. Kode yang dikutip dari artikel ini cacat dalam beberapa cara mendasar sehubungan dengan MVC. Bahkan memungkinkan model tergantung pada controller secara implisit. Omong kosong.
Falcon

3
@Crazy Eddie: lol @ downvote mengamuk. Apakah saya membuat Anda marah?
Falcon

-7
  • Pengendali mengirimkan model ke tampilan dan memproses model yang dikirimkan dari tampilan, namun tidak terikat erat dengan tampilan atau model.

Jika pengontrol terhubung erat ke tampilan, maka kita akan berada di dunia bentuk web. Anda akan memiliki kode di belakang yang akan diikat ke file template (Berlaku untuk formulir web ASP.NET)

Karena itu, pengontrol tidak digabungkan ke model atau tampilan. Itu hanya mekanisme untuk memproses permintaan dan mengirim tanggapan.

  • Tampilan tergabung erat dengan model. Buat perubahan pada model Anda (mis. Ubah propertinya) dan Anda harus membuat perubahan pada tampilan Anda.

  • Model tidak digabungkan secara ketat ke tampilan. Buat perubahan pada tampilan, dan itu tidak akan memengaruhi model.

  • Model tidak tahu apa-apa tentang pengontrol atau tampilan di mana itu dapat digunakan. Oleh karena itu model tidak digabungkan dengan pandangan atau pengontrol.

Cara lain untuk berpikir tentang ini:

  • Membuat perubahan pada pengontrol - tampilan dan model tidak akan terpengaruh

  • Buat perubahan pada model - tampilan akan pecah karena bergantung pada model

  • Membuat perubahan pada tampilan - model dan pengontrol tidak akan terpengaruh

Kopling longgar dalam proyek MVC inilah yang membuatnya mudah untuk diuji unit.


1
Ini sangat salah itu tidak lucu. Bahkan tidak layak dijelaskan. Abaikan jawaban ini sepenuhnya.
Reactgular

1
@MathewFoscarini Berhenti menangis dan tinggalkan "jawaban yang benar"
CodeART

2
hah, teori desain keseluruhan di balik MVC adalah bahwa mereka tidak saling bergantung.
Reactgular

Saya telah meninggalkan lebih banyak informasi untuk Anda, semoga masuk akal
CodeART
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.