Mengapa memasukkan logika bisnis ke dalam model? Apa yang terjadi ketika saya memiliki beberapa jenis penyimpanan?

70

Saya selalu berpikir bahwa logika bisnis harus ada di controller dan controller itu, karena itu adalah bagian 'tengah', tetap statis dan bahwa model / tampilan harus capsuled melalui antarmuka. Dengan begitu Anda dapat mengubah logika bisnis tanpa memengaruhi yang lain, program beberapa Model (satu untuk setiap basis data / jenis penyimpanan) dan puluhan tampilan (untuk platform yang berbeda misalnya).

Sekarang saya membaca dalam pertanyaan ini bahwa Anda harus selalu memasukkan logika bisnis ke dalam model dan bahwa pengontrol sangat terhubung dengan tampilan.

Bagi saya, itu tidak masuk akal dan menyiratkan bahwa setiap kali saya ingin memiliki sarana untuk mendukung database / jenis penyimpanan lain, saya harus menulis ulang seluruh model saya termasuk logika bisnis.

Dan jika saya ingin tampilan lain, saya harus menulis ulang tampilan dan pengontrolnya.

Dapatkah seseorang menjelaskan mengapa itu terjadi atau jika saya salah?

Steffen Winkler
sumber

Jawaban:

69

Jawaban ElYusubov sebagian besar paku itu, logika domain harus masuk ke model dan logika aplikasi ke controller.

Dua klarifikasi:

  • Istilah logika bisnis agak tidak berguna di sini, karena bersifat rancu. Logika bisnis adalah istilah umum untuk semua logika yang dipedulikan oleh pebisnis, memisahkannya dari sekadar teknis seperti cara menyimpan barang di database atau cara membuatnya di layar. Logika domain ("alamat email yang valid terlihat seperti ...") dan alur kerja / proses bisnis ("ketika pengguna mendaftar, minta alamat emailnya") dianggap sebagai logika bisnis, dengan yang sebelumnya jelas milik dalam model dan yang terakhir menjadi logika aplikasi yang masuk dalam controller.
  • MVC adalah pola untuk meletakkan barang-barang di layar dan memungkinkan pengguna untuk berinteraksi dengannya, itu tidak menentukan penyimpanan sama sekali . Sebagian besar kerangka kerja MVC adalah kerangka kerja tumpukan penuh yang melampaui MVC belaka dan memang membantu Anda dengan menyimpan data Anda, dan karena data yang harus disimpan biasanya ditemukan dalam model, kerangka kerja ini memberi Anda cara mudah menyimpan model Anda- data dalam database, tapi itu tidak ada hubungannya dengan MVC. Idealnya, model harus agnostik-persistensi dan beralih ke jenis penyimpanan yang berbeda tidak boleh memengaruhi model-kode sama sekali. Arsitektur penuh memiliki lapisan ketekunan untuk menangani hal ini.
Waquo
sumber
4
Sebagian besar MVC-frameworks mencampur semua penyimpanan / basis data ke dalam model agar memudahkan untuk menyimpan model Anda (seringkali dengan membuat Anda memperluas kelas model frameworks). Ini mungkin sumber kebingungan. Secara teknis, kode-model yang Anda tulis harus merupakan model aktual (lapisan domain), sedangkan kode yang disediakan oleh kerangka kerja harus berurusan dengan penyimpanan (lapisan persistensi). Misalnya, sesuatu seperti User.find (...) (dengan User menjadi model) berfungsi karena kerangka kerja menerapkan pola repositori sebagai bagian dari Model.
Waquo
3
View-Controller-Model-Storage adalah prinsip umum (meskipun hubungan antara M, V dan C harus divisualisasikan sebagai segitiga). Ketika kerangka kerja Anda menggabungkan penyimpanan ke dalam "model" mereka, ia bekerja seperti ini: View-Controller- (Model mewarisi penyimpanan dari kerangka kerja).
Waquo
2
View-Controller-Model-Storage agak kasar, karena seharusnya tidak rata. Misalnya, ketika pengontrol melakukan sesuatu seperti User.find (...) untuk mendapatkan model, ia meminta lapisan penyimpanan secara langsung daripada melalui lapisan domain.
Waquo
2
Dalam arsitektur dengan layering yang lebih hati-hati, itu akan menjadi sesuatu seperti UserRepository.find (). Yang saya maksud dengan "model" adalah kelas "model" yang disediakan oleh framework, yang Anda warisi. Objek-pengguna yang dikembalikan oleh User.find () adalah model pengguna dalam arti seseorang memodelkan apa itu pengguna, bagaimana perilaku pengguna ...
Waquo
1
@flipdoubt business logic adalah semua logika yang harus dijaga tetap sama jika Anda porting dari mvc untuk mengatakan aplikasi uwp.
Andy
23

Anda dan sebagian besar dunia pemrograman tampaknya salah memahami apa peran bagian-bagian MVC. Singkatnya, mereka adalah:

Model = logika domain

Lihat = logika output

Kontroler = logika input

Ini berarti bahwa model tersebut bertanggung jawab atas seluruh logika bisnis: segala sesuatu yang terkait dengan menggambar widget di layar, mengendarai printer, mengeluarkan data sebagai HTML, mem-parsing permintaan HTTP, dll. Tidak termasuk dalam model.

Namun, banyak kerangka kerja modern yang disebut "MVC" tidak benar-benar melakukan MVC sama sekali, atau mereka salah memberi label bagian mereka. Cukup sering, apa yang disebut "model" adalah lapisan ketekunan dari model, sementara logika bisnis berada dalam apa yang mereka sebut "pengontrol"; pengontrol yang sebenarnya biasanya hanya merupakan titik masuk pusat dengan tabel routing dan sedikit kode dalam "pengontrol" individu untuk mengirimkan input yang mereka terima ke proses bisnis yang benar. Apa yang oleh kerangka kerja ini disebut "tampilan" sebenarnya sedikit dari segalanya: beberapa logika presentasi (Lihat), sedikit penanganan input dan validasi (Pengontrol), dan beberapa logika bisnis lainnya (Model). Bagian terbesar dari tampilan aktual biasanya disebut "templat".

Anda mungkin juga ingin membaca tentang Arsitektur Multi-Tier; di mana MVC adalah jenis satu arah (aliran adalah Controller -> Model -> View), Multi-Tier adalah hal dua arah (Presentasi -> Logika -> Data -> Logika -> Presentasi), dan beberapa kerangka kerja yang berpura-pura melakukan MVC sebenarnya melakukan Three-Tier, menandai kembali Presentation to View, Logic to Controller, dan Data to Model.

tammmer
sumber
2
Saya percaya Anda salah menggambarkan Model ("Model = domain logic"), menurut saya itu lebih merupakan wadah untuk populasi dengan data, yang kemudian ditampilkan menggunakan View, dalam bentuk paling murni dari pola MVC. Tentu dalam kasus penggunaan yang sangat sederhana, Anda dapat memperlakukannya sebagai "logika domain" tapi saya yakin bahwa sebagian besar sistem yang ada akan melebihi itu dengan sangat cepat. Lebih baik untuk membagi "logika domain" menjadi lapisan / kelas yang terpisah, misalnya lapisan layanan.
A. Murray
@ A.Murray: Tentu saja Model tidak harus menjadi satu gumpalan kode monolitik, dan memisahkannya menjadi ketekunan, struktur data, dan logika domain biasanya membuat banyak akal. Namun, MVC mengelompokkan ketiga masalah ini bersama-sama dalam Model. Bagaimanapun, ketika pengontrol dan tampilan Anda mengandung logika domain, itu bukan lagi MVC yang nyata.
tdammers
@Dammers, saya suka kerapian jawaban Anda dan fokus pada logika. Menurut Anda, di manakah kekhawatiran aplikasi seperti kegigihan dan pemrosesan transaksi? Sepertinya MVC harus merupakan akronim empat huruf seperti MVCS di mana S adalah untuk layanan.
flipdoubt
15

Untuk benar-benar mengisolasi logika bisnis dan membuatnya terpisah dari infrastruktur lapisan presentasi, harus dienkapsulasi oleh layanan aplikasi. Arsitektur MVC adalah cara untuk mengimplementasikan lapisan presentasi dan harus tetap pada lingkup itu, mendelegasikan semua logika bisnis ke layanan aplikasi ini. Pikirkan model tampilan sebagai adaptor antara tampilan dan data yang perlu ditampilkan dan dibaca. Pengontrol memediasi interaksi antara model tampilan, tampilan dan layanan aplikasi yang menampung logika bisnis.

Layanan aplikasi menerapkan kasus penggunaan bisnis dan dipisahkan dari lapisan presentasi, apakah itu MVC atau yang lainnya. Pada gilirannya, layanan aplikasi dapat meng-host skrip transaksi atau desain berbasis domain .

Untuk penyimpanan, layanan aplikasi dapat merujuk repositori atau abstraksi dari mekanisme persistensi. Implementasi yang berbeda dapat didukung dengan mengabstraksi akses data ke dalam antarmuka. Biasanya, abstraksi ini bocor dan hanya sebagian portabel di seluruh implementasi dan seringkali merupakan upaya yang sia-sia untuk mencapai portabilitas penuh.

MEMPERBARUI

Saran saya didasarkan pada arsitektur Hexagonal . Dalam arsitektur heksagonal, model domain Anda (logika bisnis) adalah intinya. Inti ini dirangkum oleh layanan aplikasi yang bertindak sebagai fasad . Layanan aplikasi adalah kelas sederhana yang memiliki metode yang sesuai dengan kasus penggunaan di domain Anda. Untuk diskusi mendalam tentang layanan aplikasi, lihat Layanan di Desain Berbasis Domain . Sampel kode berisi PurchaseOrderServiceyang merupakan layanan aplikasi untuk domain pembelian. (Perhatikan bahwa layanan aplikasi tidak menyiratkan penggunaan desain berbasis domain.)

Dalam arsitektur heksagonal, lapisan presentasi MVC adalah adaptor antara model domain Anda (logika bisnis) dan GUI. Model domain tidak mengetahui lapisan presentasi, tetapi lapisan presentasi mengetahui model domain.

Solusi ini tentu saja memiliki bagian yang bergerak daripada solusi yang menempatkan logika bisnis di controller dan Anda harus mempertimbangkan kelemahan dan manfaatnya. Alasan saya menyarankan itu adalah karena saya lebih suka menjaga logika bisnis dipisahkan dari lapisan presentasi untuk memerangi kompleksitas. Ini menjadi lebih penting ketika aplikasi tumbuh.

eulerfx
sumber
Kedengarannya seperti Anda menggambarkan bajingan MVC dan MVVM yang memiliki model pengendali dan tampilan. Juga, saya pikir arsitektur yang Anda gambarkan mungkin agak berat untuk kebutuhan OP.
Waquo
jujur, saya lebih suka jawaban Waquo. Terutama karena saya tidak tahu apa yang Anda maksud dengan 'layanan aplikasi'. Bisakah Anda menjelaskan istilah itu? GoogleFU saya sepertinya tidak berfungsi di sini.
Steffen Winkler
1
@ Woquo Saya setuju bahwa arsitektur yang diusulkan mungkin berlebihan, tetapi harus dipertimbangkan. Saya tidak menyebutkan MVVM yang hanyalah cara lain untuk mengimplementasikan lapisan presentasi. Layanan aplikasi berlaku terlepas dari apakah Anda menggunakan MVC atau MVVM dan tidak ada yang saya sarankan menunjukkan kombinasi keduanya.
eulerfx
1

Tergantung pada apa yang Anda maksud dengan logika bisnis. Setiap "logika" yang memberi makna pada isi model harus dalam model. Dalam pertanyaan yang ditautkan, jawaban dengan suara tertinggi tampaknya mendefinisikan "logika bisnis" sebagai sesuatu yang berkaitan dengan data; ini masuk akal dari sudut pandang bahwa data bisnis adalah bisnisnya!

Saya pernah melihat contoh oleh pencipta Rails (saya pikir) yang sedang melakukan persis ini - tidak memasukkan "logika bisnis" dalam model. Contohnya adalah kelas pengontrol dan metode untuk pendaftaran dan masuk aplikasi - kata sandi yang disediakan dalam plaintext dienkripsi sebelum dimasukkan ke dalam atau ditanyai terhadap model (database.)

Saya tidak bisa memikirkan contoh yang lebih baik dari sesuatu yang bukan logika pengontrol dan yang termasuk langsung dalam model.

Model ini bisa menjadi antarmuka untuk berbagai penyimpanan data, mengurangi masalah portabilitas. Di sinilah orang dapat menemukan kebingungan tentang apakah atau tidak antarmuka model sebenarnya adalah "controller."

Secara umum, controller menghubungkan model dan tampilan (yang merupakan daging-dan-kentang dari aplikasi.) Dalam pengembangan Kakao dapat menjadi sederhana ke titik di mana controller ditangani melalui GUI XCode (objek controller dan binding.)

Bagian "Pola Desain" GoF di MVC, dikutip secara longgar:

Triad kelas MVC digunakan untuk membangun antarmuka pengguna di Smalltalk-80. Model adalah objek aplikasi, tampilan adalah presentasi layarnya, dan Pengontrol menentukan cara UI bereaksi terhadap input pengguna. MVC memisahkan pandangan dan model dengan membuat protokol berlangganan / memberitahukan di antara mereka. Diagram berikut menunjukkan model dan tiga tampilan. Kami telah meninggalkan pengontrol untuk kesederhanaan.

MVC adalah tentang UI. Fokusnya adalah pada model dan tampilan - mendefinisikan dan menampilkan data. Perhatikan "berlangganan / beri tahu protokol" - ini adalah tempat controller Anda masuk. Anda dapat membangun semua tampilan yang Anda inginkan; selama mereka mematuhi protokol Anda tidak akan pernah harus menyentuh model atau pengontrol.

Jika Anda berbicara pengembangan web secara khusus, IMHO banyak kerangka kerja web populer cepat dan longgar dengan istilah MVC dan definisi komponennya.

Duke
sumber
Saya adalah pengembang C # / Java (hanya beberapa proyek di sana). Tampaknya saya salah mengerti apa yang dilakukan model. Menempatkan 'logika bisnis' ke dalam pengontrol benar-benar hanya efek samping (jalur pemikiran saya berlanjut 'oke, saya sudah model untuk data (baca: koneksi / penyimpanan basis data), jadi logika bisnis saya perlu masuk ke pengontrol karena Saya harus menerapkannya sebelum menyimpan data dalam database '. Hanya harus memindahkan semuanya satu tingkat ke bawah dari controller. Sebenarnya, itu memecahkan masalah yang saya miliki saat ini (mendukung MySQL dan MSSQL dalam satu program)
Steffen Winkler
0

Mengapa Anda tidak memperkenalkan lapisan layanan?

Maka controller Anda akan ramping dan lebih mudah dibaca, maka semua fungsi controller Anda akan menjadi tindakan murni.

Anda dapat menguraikan logika bisnis sebanyak yang Anda butuhkan di dalam lapisan layanan. Penggunaan kembali kode lebih baik dan tidak ada dampak pada model dan repositori.

Anil
sumber