Haruskah logika penyortiran ditempatkan dalam model, tampilan, atau pengontrol? [Tutup]

157

Saya memiliki daftar turun bawah yang menampilkan nilai dari tabel ke pengguna akhir. Saya ingin agar nilai-nilai ini diurutkan berdasarkan abjad.

Menurut desain MVC yang tepat, pada lapisan apa saya harus menempatkan logika penyortiran saya: model, tampilan, atau pengontrol?

EDIT : Menanggapi pertanyaan LarsH, "Apakah maksud Anda kode yang menentukan jenis pesanan apa yang diinginkan? Atau kode yang melakukan jenis itu?", Saya awalnya merujuk pada kode yang menentukan jenis urutan apa yang diinginkan.

Ryan Kohn
sumber
6
Untuk menyelesaikan pertikaian dalam komentar, akan sangat membantu jika Anda mengatakan apa yang Anda maksud dengan "logika penyortiran". Apakah maksud Anda kode yang menentukan jenis pesanan apa yang diinginkan? atau kode yang melakukan pengurutan?
LarsH
9
Desain MVC bukanlah sesuatu yang istimewa atau ajaib - itu sebenarnya hanya titik awal. membuatnya sesuai dengan kebutuhan Anda dan ingat Anda dapat refactor kapan saja. Saya perhatikan bahwa vendor yang berbeda akan mendefinisikan ulang apa yang masuk ke controller atau tampilan berdasarkan kebutuhan toolkit mereka sehingga sulit untuk menemukan kesepakatan. Yang penting adalah untuk memisahkan Model Anda dari View / Controller Anda. Anda mungkin juga mendapatkan jarak tempuh lebih banyak dari pola MVP, saya percaya ini sedikit lebih spesifik di area ini.
Bill K
9
Mungkin ini harus dimigrasikan ke Programmer.
Alfredo Osorio
57
Jelas di controller. Entah itu atau modelnya. Atau pemandangan.
mob
2
Jelas tidak pernah, tidak pernah, tidak pernah, dalam pandangan.
contactmatt

Jawaban:

49

(Catatan: kutipan dan kutipan ini diambil dari jawaban @ dasblinkenlight , tetapi kami tidak setuju dengan interpretasi kami tentang hal itu. Baca postingnya dan buat keputusan sendiri).

Menurut deskripsi MVC ,

Pengontrol dapat mengirim perintah ke tampilan terkait untuk mengubah presentasi tampilan model (misalnya, dengan menggulir dokumen). Ini dapat mengirim perintah ke model untuk memperbarui keadaan model (misalnya mengedit dokumen).

Logika pengurutan (mis., Algoritma sortir komparator / pengurutan) termasuk dalam model karena berisi aturan bisnis dan data negara. Karena mengubah cara data model diurutkan jatuh tepat ke dalam kategori "ubah presentasi tampilan model", controller bertanggung jawab untuk "melakukan penyortiran" dengan memanggil metode model.changeSortedState ().

KyleM
sumber
8
Bagaimana jika data yang sama ditampilkan dalam dua tampilan berbeda, diurutkan secara berbeda?
s4y
Itu juga harus dilakukan dengan cara yang sama, model.SortAscending () dan model.SortDescending () dan dipanggil oleh Controller.
Brij
1
@ Brij Dalam MVC yang tepat, dapatkah dua tampilan tidak berbagi model yang sama?
KOVIKO
@Sidnicious Jika masuk akal untuk memiliki satu metode penyortiran yang mengambil parameter berbeda. Misal public void Sort(bool sortByDescending = false), di mana jika false itu diurutkan dengan naik. Atau hanya memiliki dua metode penyortiran yang berbeda jika logikanya sangat berbeda.
MattMcGowan
@Sidnicious memiliki dua model berbeda yang mendelegasikan segalanya kecuali logika penyortiran ke model ketiga tunggal. docs.google.com/drawings/d/…
rightfold
62

Siapa yang mengendalikan urutan pengurutan?

Diagram MVC sederhana(Dari Wikipedia )

1) Urutan alami dalam data itu sendiri:

Urutan adalah bagian dari Model, jadi harus pergi ke sana. Tarik mentah "semua data" akan mengembalikan data dalam urutan yang diurutkan, dan tidak ada antarmuka untuk memilih urutan.

2) Pengguna harus mengontrol cara mereka melihat data:

Tampilan akan menyediakan antarmuka (seperti panah naik / turun) yang berinteraksi dengan Controller, dan Model memahami data dengan cukup baik untuk melakukan pengurutan yang diminta pada data. Namun, tarikan data mentah tidak harus harus diurutkan, tidak seperti dalam (1).

Dalam kedua kasus tersebut,

Tampilan tidak mengerti bahwa ada semacam hal yang terjadi, selain itu kemampuan untuk menunjukkan arah sortir mana yang telah dipilih. Jangan menaruh logika di sana.

Peringatan kecil

Fungsionalitas penyortiran bisa murni di View, dalam satu keadaan (yang bisa saya pikirkan begitu saja; mungkin ada lebih):

Sortir "bodoh" di mana semua data sudah ada dalam tampilan dan tidak perlu menggunakan pengetahuan domain apa pun untuk melakukan sortir. Perbandingan string atau angka yang sangat sederhana, misalnya. Ini tidak mungkin di, misalnya, hasil pencarian pada halaman web ketika hasilnya cenderung dipecah menjadi beberapa halaman.

Izkata
sumber
58
Tampilannya bisa melihat pengguna !?
Farzher
41
Model memperbarui tampilan !?
deceze
13
Artikel wikipedia itu menyebalkan: bagian "Interaksi komponen" bertentangan dengan diagram yang ditunjukkan di sebelah kanan (yang baru saja Anda posting di sini). Kedua, model tidak "memperbarui" tampilan. Ini MEMPERHATIKAN tampilan ketika telah ada perubahan keadaan. Tampilan memutuskan bagaimana memperbarui. Ugh. Anda bertanya-tanya mengapa ada 1000 jawaban berbeda untuk pertanyaan ini ketika ada begitu banyak informasi yang tidak jelas yang beredar.
KyleM
4
@ cHao Tentu. Kita bisa setuju bahwa grafik Wikipedia cukup aneh, bukan? :)
deceze
6
@StephenSarcsamKamenar dan yang lainnya: Tidak, gambarnya masuk akal: Menunjukkan aliran data , bukan koneksi kode.
Izkata
18

Menurut deskripsi MVC ,

Pengontrol dapat mengirim perintah ke tampilan terkait untuk mengubah presentasi tampilan model (misalnya, dengan menggulir dokumen). Ini dapat mengirim perintah ke model untuk memperbarui keadaan model (misalnya mengedit dokumen).

Menurut ini, pengurutan logika termasuk dalam pengontrol, karena mengubah cara data model diurutkan jatuh tepat ke dalam kategori "mengubah tampilan presentasi model".

EDIT: Untuk memperjelas beberapa kesalahpahaman yang disuarakan dalam komentar, "logika penyortiran" bukanlah kode yang melakukan penyortiran; itu adalah kode yang mendefinisikan semacam itu. Logika pengurutan membandingkan masing-masing item satu sama lain untuk menetapkan suatu pesanan (misalnya melalui instance IComparator<T>) atau berisi logika yang membangun objek yang akan digunakan untuk pemesanan oleh sistem eksternal (misalnya melalui instance dari IOrderedQueryable<T>). Logika ini termasuk dalam pengontrol Anda, karena memerlukan pengetahuan yang terkait dengan sisi "bisnis" dari aplikasi Anda. Ini sepenuhnya cukup untuk melakukan pengurutan, tetapi terpisah dari kode yang sebenarnya melakukanItu. Kode yang mengurutkan mungkin dalam pandangan Anda, dalam model Anda, atau bahkan di lapisan kegigihan yang mendukung model Anda (misalnya database SQL Anda).

dasblinkenlight
sumber
12
-1 Bagaimana Anda bisa menyimpulkan ini dari kutipan itu? Adakah yang mengatakan bahwa pengontrol seharusnya mengambil informasi dari model? Pengendali mengirim perintah untuk mengubah status. Tidak ada yang dikatakan tentang ekstraksi atau manipulasi informasi.
tereško
3
@ tereško Bagaimana Anda bisa menyimpulkan dari jawaban saya bahwa controller perlu mengambil informasi dari model? Dengan "menyortir logika" Maksud saya hanya logika yang diperlukan untuk membuat pemesanan - dalam istilah C #, yang menyediakan implementasi IComparer<T>. "Mekanika boilerplate" yang tersisa dari penyortiran, termasuk pengambilan data dari model, tergantung pandangan.
dasblinkenlight
3
".. logika penyortiran termasuk dalam controller .." , apa lagi artinya ini?
tereško
3
"Kontroler dapat mengirim perintah ke tampilan terkait untuk mengubah presentasi tampilan" benar-benar terdengar seperti tampilan yang akan melakukan penyortiran, sebagai respons terhadap perintah dari controller.
Samuel Edwin Ward
1
@KyleM Tetapi tampilan tidak selalu memiliki cukup pengetahuan untuk mengandung logika penyortiran. Misalnya, pertimbangkan bidang yang memiliki kode numerik yang sesuai dengan salah satu enum {Unknown, Pass, Fail}. Asumsi lebih lanjut yang Unknownharus selalu diurutkan terakhir, terlepas dari urutan naik atau turun yang dipilih pengguna. Menempatkan logika ini dalam tampilan akan memberi tahu pandangan Anda terlalu banyak tentang sifat bisnis dari data di dalam codebidang. Tampilan seharusnya tidak mengetahuinya: yang diketahui hanyalah bahwa pengguna melakukan isyarat "sort" (mis. Mengklik header); sisanya terserah controller.
dasblinkenlight
10

Bukan dari salah satu di atas. Penyortiran adalah logika bisnis, dan logika bisnis tidak termasuk dalam ketiganya. Tidak setiap bagian kode dalam aplikasi Anda akan menjadi model, tampilan, atau pengontrol.

Apa yang biasanya saya lakukan di aplikasi MVC saya adalah saya memiliki lapisan layanan yang melakukan semua logika bisnis. Metode di lapisan layanan harus memiliki API yang bersih dan sederhana dengan parameter yang dinamai dengan baik. Anda kemudian dapat memanggil metode-metode itu dari pengontrol Anda untuk memanipulasi data dalam model.

Dalam pengertian itu, pengurutan adalah "di controller", tetapi kode itu sendiri yang melakukan pengurutan tidak boleh diimplementasikan di controller, hanya dipanggil dari sana.

tidak
sumber
5
Saya baru-baru ini diberitahu bahwa beberapa orang menganggap "lapisan layanan" (logika bisnis) sebagai bagian dari model.
Marvo
@ Marvo Saya pikir ada beberapa kasus di mana potongan-potongan logika tertentu sangat terkait erat dengan tipe data mereka sehingga masuk akal untuk merangkum mereka bersama dalam satu kelas. (fungsi waktu dan tanggal misalnya). Secara umum, saya merasa ini bekerja paling baik ketika objek model tidak melakukan apa-apa selain menyimpan data.
Nont
Lalu di mana logika bisnis "hidup" dalam pola MVC?
Marvo
2
Hanya karena aplikasi menggunakan pola MVC, tidak berarti bahwa setiap bagian dari kode dalam aplikasi akan menjadi model, tampilan atau pengontrol. Itu mengambil pola desain terlalu harfiah. Misalnya, aplikasi Anda mungkin memiliki beberapa file konfigurasi. File konfigurasi itu bukan memodelkan data pengguna, juga tidak menyajikan tampilan, atau mengendalikan aliran data melalui model ke tampilan. Ini adalah file konfigurasi, yang merupakan jenisnya sendiri.
Nont
Seseorang dapat dengan mudah mempertimbangkan bagian file konfigurasi dari model. Model tidak harus menjadi basis data. Saya tidak mengatakan Anda benar atau salah. Saya hanya menyarankan agar Anda, seperti yang baru-baru ini saya lakukan (karena saya memiliki pandangan yang sama dengan Anda) google sedikit membahas dan melihat apa yang orang lain katakan.
Marvo
8

Jelas bukan controller: Ini mengirim pesan untuk dilihat dan dimodelkan tetapi harus melakukan pekerjaan sesedikit mungkin. Jika pengguna dapat mengubah pengurutan bahwa permintaan akan ditangani oleh pengontrol dengan menginformasikan model atau pandangan tentang itu.

Mungkin View jika itu adalah View murni. Jika Aplikasi berfungsi dengan baik tanpa memilah maka penyortiran hanyalah bagian dari representasi dan harus masuk dalam tampilan.

Jika pemesanan merupakan bagian yang tidak dapat dipisahkan dari domain, maka harus dimasukkan dalam model.

Jens Schauder
sumber
Apakah "menyediakan pembanding atau deskriptor semacam" dianggap sebagai "melakukan pekerjaan"? Karena logika pengurutan dienkapsulasi dalam komparator atau deskriptor pengurutan, bahkan jika "pekerjaan pengurutan" dilakukan dalam metode pengurutan atau bagian belakang model.
dasblinkenlight
Tergantung pada apa yang Anda maksud dengan memberikan: lewat tidak masalah. Tetapi pembanding harus menjadi bagian dari model atau tampilan, bukan pengontrol.
Jens Schauder
6
  • Tampilan adalah bagian dari MVC yang seharusnya mengandung logika presentasi.
  • Lapisan model adalah tempat logika bisnis terkandung.
  • Pengontrol hanya mengubah keadaan keduanya, berdasarkan input pengguna.

Jadi pilihannya adalah - apakah Anda pikir ini adalah bagian dari logika bisnis domain atau logika presentasi.

Jika Anda menerapkan MVC Model2 yang tepat atau pola MVC klasik, maka saya akan mengatakan bahwa pemesanan data yang disediakan oleh lapisan model harus dipicu oleh permintaan tampilan ke lapisan model. Lihat meminta data yang dipesan, lapisan model menyediakannya.

Tapi, karena Anda menggunakan interpretasi ASP.NET MVC tentang pola MVC, yang sedikit berbeda dari MVC standar Anda - contoh ViewModel harus meminta informasi yang dipesan dari lapisan model (untuk beberapa alasan kerangka ASP.NET berpikir bahwa templat harus disebut "views" dan views harus disebut "viewmodels" .. ini aneh).

tereško
sumber
12
Anda terus menurunkan beberapa jawaban menerapkan asumsi Anda sendiri tentang apa yang mereka maksud dengan "logika penyortiran". Asumsi Anda benar-benar salah - logika penyortiran tidak, dan tidak pernah, termasuk pengambilan.
dasblinkenlight
1
@dasblinkenlight, ya, saya downvotes beberapa topik karena semuanya menyiratkan bahwa controller harus melakukan penyortiran. Itu salah. Dan .. orang-orang .. tolong jangan tandai komentar saya hanya karena Anda tidak setuju.
tereško
Hanya untuk memperjelas: Saya tidak mengecilkan jawaban Anda karena itu tidak salah, dan saya tidak pernah menandai komentar Anda, karena saya tidak merasa kasar dengan cara apa pun. Jujur, saya tidak tahu bagaimana jawaban Anda berhasil mendapatkan begitu banyak downvotes: Saya pikir mereka salah dipahami.
dasblinkenlight
@dasblinkenlight naah .. saya mengamuk tentang komentar saya yang dalam topik ini lenyap.
tereško
5

Saya biasanya akan melakukannya di controller untuk tetap sejalan dengan pola sesuai jawaban lainnya. Lihat di bawah untuk alasan.

Saya telah merenungkan ini dan membaca jawaban dan materi terkait dan secara pragmatis saya akan mengatakan itu akan tergantung pada aplikasi Anda misalnya:

Apakah itu aplikasi menengah / besar dan / atau memiliki beberapa UI yang terkait dengannya (yaitu Aplikasi Windows, antarmuka Web, dan antarmuka Telepon).

  • Dalam hal ini saya mungkin akan membangun sebuah lapisan layanan dan meletakkannya di objek bisnis dan kemudian memanggil metode yang sesuai dari controller.

Jika ini adalah situs web UI tunggal yang didefinisikan dengan baik dan Anda menggunakan sesuatu seperti EF Code First dan Anda tidak memiliki atau tidak memiliki niat untuk membuat lapisan layanan dan berencana untuk menggunakan metode Extension sederhana di luar kotak untuk mencapainya:

  • Dalam hal ini saya mungkin akan meletakkannya di controller sebagai pragmatis yang paling sesuai dengan waktu / anggaran.

Jika sama dengan NAMUN di atas tidak dapat diimplementasikan dengan metode ekstensi di luar kotak.

  • Saya mungkin memilih untuk pop di kelas Model (jika itu benar-benar dipesan lebih dahulu untuk jenis tunggal) karena akan lebih tepat di sini daripada di controller. Jika semacam itu dapat diterapkan ke lebih dari satu kelas maka saya akan menerapkannya dalam metode ekstensi dan kemudian memanggilnya di controller.

Untuk menyimpulkan:

Jawaban dogmatis: Lapisan Layanan

Jawaban pragmatis: Biasanya controller

Luke Baughan
sumber
Di mana definisi controller bertanggung jawab untuk "menyiapkan data untuk dilihat"?
tereško
1
@ tereško: Di mana model "pasif" seperti yang dijelaskan di sini msdn.microsoft.com/en-us/library/ff649643.aspx di bagian variasi. Lihat "HTTP adalah contoh dari ini". Sementara seorang purist mungkin memperdebatkan hal ini, akan lebih mudah bagi pemula yang memulai di MVC di mana mereka mungkin menggunakan EF atau model lain secara langsung di controller dan tidak melalui BAL untuk memikirkannya dengan cara ini menurunkan penghalang untuk memahami pola lebih lanjut.
Luke Baughan
1
apa yang Anda bicarakan adalah "model anemia".
tereško
Point mencatat, saya telah menghapus deskripsi yang menyinggung seperti yang Anda sarankan. Sorakan untuk input!
Luke Baughan
3

Saya sarankan menyortir data dari tabel-data yang cukup kecil untuk berguna dalam daftar dropdown-harus berasal dari DB yang sudah diurutkan melalui kueri. Bagi saya, itu menjadikan model tempat penerapan semacam itu.

Jika Anda bertekad untuk melakukan pengurutan dengan tangan, saya pikir ada argumen yang baik untuk menggunakan model atau pengontrol sebagai tempat pilihan Anda untuk logika. Keterbatasan akan menjadi kerangka kerja khusus Anda. Saya lebih suka mengelola data hanya dalam model. Saya menggunakan pengontrol untuk mengawinkan data (model) dan presentasi (tampilan) seperti yang telah saya (sendiri) ajarkan.

B0nk3r
sumber
2

Sementara saya setuju secara prinsip dengan gagasan bahwa pengurutan adalah Logika Bisnis karena dengan memecahnya ke asalnya Anda akan berakhir dengan sesuatu seperti "Klien ingin halaman Produk ditampilkan dengan gambar diurutkan berdasarkan tanggal" maka menjadi jelas bahwa urutan pengurutan untuk data biasanya tidak sewenang-wenang - bahkan jika tidak ada pengurutan karena itu masih merupakan keputusan bisnis karena kelalaian (daftar kosong masih daftar).

TAPI ... Jawaban ini tampaknya tidak memperhitungkan kemajuan teknologi ORM, saya hanya bisa berbicara sehubungan dengan Entity Framework (mari kita hindari argumen tentang apakah ini benar ORM, itu bukan intinya) dari Microsoft sebagai itulah yang saya gunakan, tapi saya yakin ORM lain menawarkan fungsionalitas serupa.

Jika saya membuat tampilan Sangat Diketik untuk kelas Produk menggunakan MS MVC dan Entity Framework dan ada hubungan kunci asing antara tabel Produk dan Gambar (misalnya FK_Product_Image_ProductId) maka saya akan langsung bisa mengurutkan dengan cepat gambar selama tampilan mereka menggunakan sesuatu seperti ini dalam tampilan:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

Ada disebutkan tentang lapisan Logika Bisnis, yang saya juga gunakan untuk melakukan 80% dari logika bisnis saya, tapi saya tidak akan menulis fungsi semacam ke dalam lapisan Logika Bisnis saya yang meniru sesuatu yang keluar dari kotak dari Kerangka Entitas.

Saya tidak berpikir ada jawaban yang benar untuk pertanyaan ini, selain mengatakan itu; Anda harus abstrak logika bisnis yang kompleks di mana mungkin tetapi tidak dengan biaya menciptakan kembali roda.

rampok
sumber
Saya memikirkan hal yang sama, jawaban di sini sepertinya tidak memperhitungkan ORM dan metode Extension. Dalam kebanyakan kasus, pengurutan logika akan sesederhana myList.OrderBy(x => x.CreationDate)- benar-benar tidak perlu memperkenalkan lapisan tambahan yang tidak perlu hanya untuk melakukan ini. Untuk menambah ini, apa yang akan mereka lakukan jika mereka membutuhkan data halaman dan diurutkan? Minta seluruh tabel, urutkan, lalu simpan yang mereka butuhkan? Seseorang bisa saja menelepon myList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)dan tidak ada data yang tidak perlu diambil.
Balázs
1

Asumsikan bahwa Anda memiliki situs web MVC, situs web WebForms, dan aplikasi seluler.

Jika Anda ingin menyortir agar konsisten di antara lapisan presentasi ini, maka saya akan mengatakan semacam di luar lapisan presentasi. Layanan akan menjadi kandidat yang baik.

Kalau tidak, saya akan menyimpan logika itu dalam model tampilan. Mengapa? Karena itu akan dapat digunakan kembali dan mudah diuji.


sumber
0

Dari tiga yang Anda daftarkan, saya akan mengatakan bahwa itu termasuk dalam controller. Saya tidak terlalu suka menempatkan logika semacam ini di controller. Saya biasanya membuat lapisan layanan yang berkomunikasi dengan controller yang akan bertanggung jawab untuk berkomunikasi dengan penyimpanan data dan menangani logika penyortiran. Untuk aplikasi kecil, tidak masalah untuk duduk di controller.

Singkirkan
sumber
2
Itu akan menempatkan logika lebih pada sisi model, benar?
Ryan Kohn
Ya, pemahaman saya tentang "lapisan layanan" adalah bahwa itu bagian dari model.
Marvo
0

Ini adalah pertanyaan yang diajukan dengan asp.net dalam pikiran, tetapi karena seseorang memang menyebutkan Rails, saya pikir akan menarik untuk mempertimbangkan masalah dalam konteks itu. Dalam Rails, wajar dan cukup umum untuk melakukan penyortiran bersama dengan pengambilan sebagai tindakan pengontrol, karena kerangka kerja dan ketentuan api ActiveRecord / ActiveQuery untuk itu. Di sisi lain, dimungkinkan untuk menentukan semacam urutan penyortiran khusus untuk item statis dan memasukkannya ke dalam model yang akan digunakan oleh pengontrol, sehingga model tersebut dapat memainkan bagian dalam logika penyortiran meskipun tidak dilakukan. operasi secara langsung. Apa pun itu, dapat dikatakan bahwa menempatkan semacam logika dalam pandangan umumnya tidak disukai.

Saya sedikit geli bahwa beberapa jawaban benar-benar menentang meletakkan semacam itu di controller atau model, dan saya menemukan mereka terlalu bagus untuk seleraku, tapi saya kira itu tergantung pada sifat kerangka kerja yang digunakan dan konvensi biasa yang terkait dengan Itu. Saya juga setuju dengan komentar Bill K bahwa pertama-tama berpisah lebih penting.

Prusswan
sumber