Apakah mungkin bagi logika bisnis untuk tidak masuk ke tampilan?

31

Saya telah mengembangkan untuk beberapa proyek aplikasi web selama 3 tahun terakhir, baik pribadi maupun di tempat kerja, dan sepertinya saya tidak tahu apakah mungkin untuk setidaknya beberapa logika bisnis tidak berakhir di lapisan tampilan aplikasi.

Dalam kebanyakan kasus akan ada masalah seperti "Jika pengguna telah memilih opsi x maka aplikasi harus memungkinkannya untuk memberikan info untuk y, jika tidak maka ia harus menyediakan info z". Atau lakukan beberapa operasi AJAX yang harus menerapkan beberapa perubahan pada model tetapi BUKAN komit sampai pengguna secara eksplisit memintanya. Ini adalah beberapa masalah paling sederhana yang saya temui dan saya tidak tahu bagaimana mungkin untuk menghindari logika kompleks dalam tampilan.

Sebagian besar buku yang saya baca menggambarkan MVC biasanya menampilkan beberapa contoh yang sangat sepele, seperti operasi CRUD yang hanya memperbarui data di server dan menampilkannya, tetapi CRUD tidak demikian pada kebanyakan aplikasi kaya.

Apakah mungkin untuk mencapai memiliki pandangan tanpa logika bisnis sama sekali?

vdaras
sumber
2
Lihatlah derivasi MVC, MVP dan MVVM (lihat en.wikipedia.org/wiki/Model_View_Presenter dan en.wikipedia.org/wiki/Model_View_ViewModel ), mereka mungkin adalah yang Anda cari.
Doc Brown
terkait (mungkin duplikat): Kelas decoupling dari antarmuka pengguna
nyamuk
2
Tampilan adalah manifestasi eksternal dan kasat mata dari data dan logika Anda. Tidak mungkin untuk tampilan TIDAK untuk menyajikan logika bisnis. Atau Anda mengatakan bahwa tampilan tidak boleh memiliki kode di dalamnya? Anda tentu dapat membuat tampilan hanya HTML.
BobDalgleish
Anda mungkin melihat animasi templat ; sementara ini mungkin tidak akan menghapus semua logika dari lapisan tampilan , sepertinya itu akan menyebabkan pemisahan yang sedikit lebih baik.
paul
Saya pikir pertanyaan yang lebih baik adalah apakah lebih baik untuk melihat data untuk mencemari model atau lebih baik untuk tampilan mengandung logika tampilan yang terkait dengan logika bisnis? Itu adalah skenario dunia yang lebih nyata. Pertanyaan Anda pada dasarnya adalah menganjurkan polusi model untuk mendukung pandangan karena itu akan menjadi satu-satunya cara untuk mencapai apa yang Anda minta.
Dunk

Jawaban:

22

Apakah mungkin untuk mencapai memiliki pandangan tanpa logika bisnis sama sekali?

Saya menemukan ini pertanyaan yang sulit untuk dijawab. (Pertanyaan yang memancing pikiran!)

Secara teoritis, ya, tergantung pada apa yang kami definisikan sebagai logika bisnis. Dalam praktiknya, pemisahan yang ketat menjadi jauh lebih sulit, dan mungkin bahkan tidak diinginkan.

Pemisahan masalah adalah cara yang bagus untuk berpikir tentang membangun perangkat lunak: ini memberi Anda ide tentang di mana menempatkan kode, dan itu memberi pengelola gagasan yang bagus tentang ke mana harus mencari kode. Saya akan berpendapat bahwa pada dasarnya mustahil bagi manusia untuk membangun perangkat lunak yang berfungsi tanpa pemisahan kekhawatiran. Kami membutuhkan ini.

Tetapi, seperti semua hal lainnya, ada pertukaran. Lokasi konseptual terbaik mungkin bukan lokasi terbaik karena alasan lain. Mungkin ada terlalu banyak beban di server web Anda, jadi Anda menambahkan beberapa javascript ke halaman web Anda untuk menangkap kesalahan input yang mudah sebelum mereka menekan server Anda; sekarang Anda memiliki beberapa logika bisnis dalam pandangan Anda.

Pandangan itu sendiri, dengan sendirinya, tidak memiliki nilai tanpa logika bisnis. Dan agar efektif dalam penggunaan dan tampilan, secara implisit atau eksplisit, pandangan akan memiliki pengetahuan tentang proses bisnis yang terjadi di belakangnya. Kita dapat membatasi jumlah pengetahuan itu, dan kita dapat menutup bagian-bagiannya, tetapi pertimbangan praktis sering kali memaksa kita untuk 'memecah' pemisahan masalah.

JvR
sumber
2
The best conceptual location may not be the best location for other reasons: Bravo !!
Magno C
8

Saya biasanya melakukan ini: jika pengguna telah memilih opsi x, lihat panggilan

controller->OptionXChanged()

Kemudian controller mengaktifkan y pada tampilan:

view->SetEnableInfoY(True) // suppose False=SetDisable

Tampilan memberi tahu pengontrol tentang apa yang terjadi tanpa memutuskan apa pun.

Fil
sumber
+1. Masalah sepele OP biasanya akan ditangani seperti ini dalam aplikasi nontrivial
dev_feed
Menempatkan logika ini dalam pengontrol memiliki dua masalah: 1) mempersulit pengujian unit, dan tidak mungkin untuk mendukung beberapa tampilan data yang sama.
kevin cline
4

Saya mempertanyakan apakah contoh yang Anda jelaskan benar-benar logika bisnis. Contoh yang Anda gambarkan adalah operasi yang dapat dilakukan pada sistem. Ini adalah bagaimana Anda memilih untuk menyajikan pilihan kepada pengguna yang mungkin memberi kesan bahwa Anda melakukan logika bisnis dalam tampilan.

Dari sudut pandang "View" hanya menyediakan InfoY atau InfoZ ke sistem. Hanya karena implementasi UI Anda melakukan beberapa pembaruan dinamis berdasarkan pilihan operator (mis. Mengaktifkan InfoY atau InfoZ) tidak membuat logika bisnis fungsionalitas. Ini benar-benar melihat logika implementasi. Anda bisa saja memberikan operator pilihan untuk memasuki InfoY atau InfoZ tanpa seluruh hal yang memungkinkan. Dalam konteks itu, apakah Anda masih menganggapnya sebagai logika bisnis? Jika tidak, maka hal yang sama berlaku untuk bidang info yang mengaktifkan / menonaktifkan secara dinamis.

Sama berlaku untuk contoh komit. Ini adalah 2 operasi terpisah yang diperlukan sistem untuk bekerja dengan baik. Tampilan Anda harus dapat memulai tindakan yang tepat untuk melakukan fungsi yang diinginkan. Apakah mengetahui cara menggunakan sistem Anda berarti bahwa logika bisnis bocor? Saya bisa melihat bagaimana seseorang bisa mengatakan ya tetapi jika Anda percaya seperti itu maka kenyataannya adalah bahwa tidak ada pemisahan logika bisnis dari apa pun. Anda harus tahu apa yang dilakukan sistem / bekerja untuk mencapai apa pun yang bermakna. Kalau tidak, akan sangat mudah untuk membuat View dan Controller generik tunggal yang bekerja dengan setiap aplikasi MVC yang mungkin. Yang kita tahu tidak mungkin.

Intinya, saya pikir definisi Anda tentang logika bisnis tidak sama dengan definisi orang lain.

Dunk
sumber
1

Saya bekerja dengan cara ini (Struts2 + Hibernate):

Tindakan Struts saya hanya bertanggung jawab untuk menampilkan informasi di peramban web. Tidak berpikir.

Pengguna -> Tindakan -> Layanan -> Repositori -> Akses Data

Atau:

Saya Ingin Melihat -> Cara melihat -> Apa yang Harus Dilakukan -> Cara Mendapatkan -> Di mana mendapatkan

Jadi, di lapisan pertama (tampilan) saya punya sesuatu seperti:

public String execute ()   {
    try {
        CourseService cs = new CourseService();
        Course course = cs.getCourse(idCourse);
    } catch (NotFoundException e) {
        setMessageText("Course not found.");
    } catch (Exception e) {

    }
    return "ok";
}

Seperti yang Anda lihat, "pandangan" saya tidak berpikir. Itu meminta layanan (untuk mengelola kursus) kursus tertentu. Layanan itu dapat melakukan banyak hal lebih banyak, seperti laporan, seraches, dan sebagainya. Hasilnya selalu berupa daftar atau objek tertentu (seperti contoh). Layanan adalah mesin nyata, menerapkan aturan dan mengakses Repositori (untuk mengelola data).

Jadi, jika saya meletakkan Layanan, Gudang, dan DAOS saya di perpustakaan yang berbeda, saya dapat menggunakannya bahkan dalam program berbasis teks, atau sistem desktop berbasis Window dengan tidak mengubah apa pun.

Layanan tahu apa yang harus dilakukan, tetapi tidak tahu bagaimana menunjukkannya. Pandangan tahu bagaimana menunjukkan, tetapi tidak tahu apa yang harus dilakukan. Sama dengan Layanan / Repositori: Layanan mengirim dan meminta data, tetapi tidak tahu di mana data itu dan bagaimana cara membawanya. Repositori "membuat" data mentah untuk membeli objek agar Layanan dapat bekerja dengannya.

Tetapi Repositori tidak tahu apa-apa tentang database. Jenis basis data (MySQL, PostgreSQL, ...) berkaitan dengan DAO.

Anda dapat mengubah DAO jika Anda ingin mengubah database dan itu tidak akan mempengaruhi lapisan atas. Anda dapat mengubah Repositori jika Anda ingin memperbarui manajemen data Anda, tetapi ini tidak boleh memengaruhi DAO dan lapisan atas. Anda dapat mengubah Layanan jika Anda ingin mengubah logika Anda, tetapi ini tidak boleh mengacaukan dengan lapisan di atas atau di bawah.

Dan Anda dapat mengubah apa pun yang terlihat, bahkan teknologi (web, desktop, teks) tetapi ini tidak boleh menyiratkan sentuhan apa pun di bawah.

Logika bisnis adalah Layanan. Tetapi cara berinteraksi dengan ini adalah dengan melihat. Tombol apa yang harus ditunjukkan sekarang? Bisakah pengguna melihat tautan ini? Pikirkan sistem Anda adalah program berbasis konsol: Anda harus menolak jika pengguna yang salah memilih #> myprogram -CourseService -option=getCourse -idCourse=234atau menghentikannya untuk menekan tombol untuk menulis perintah ini?

Berbicara dalam sistem berbasis web (Struts + JavaEE) Saya memiliki paket pengontrol GUI terpisah. Dalam Action view saya memberikan pengguna yang dicatat dan kelas memberi saya tombol (atau elemen antarmuka yang saya inginkan).

                <div id="userDetailSubBox">
                    <c:forEach var="actionButton" items="${actionButtons}" varStatus="id">
                        ${actionButton.buttonCode}
                    </c:forEach>
                </div>

Dan

private List<ActionButton> actionButtons;

Ingatlah untuk menghindari hal ini dari layanan. Ini adalah hal-hal LIHAT. Simpan di Struts Actions. Setiap interaksi antarmuka harus sepenuhnya terpisah dari kode bisnis nyata, jadi jika Anda mem-porting sistem Anda, akan mudah memotong apa yang tidak Anda perlukan lagi.

Magno C
sumber
1

Dalam kebanyakan kasus akan ada masalah seperti "Jika pengguna telah memilih opsi x maka aplikasi harus memungkinkannya untuk memberikan info untuk y, jika tidak maka ia harus memberikan info z"

Itu logika untuk model, bukan tampilan. Ini mungkin "view-model", dibuat khusus untuk mendukung UI, tetapi masih model logika. Urutan kontrol adalah:

  • Kontroler melampirkan pawang untuk melihat acara
  • Lihat melampirkan penangan untuk acara model
  • Pengguna memilih opsi X.
  • Tampilan memunculkan acara "Opsi X Dipilih"
  • Pengendali menerima acara dan memanggil model.selectOptionX ()
  • Model memunculkan acara "Model state berubah"
  • Tampilan menerima model mengubah acara dan memperbarui tampilan agar sesuai dengan keadaan baru: inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());

UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------| Ini adalah pola MVC klasik. Dimungkinkan untuk sepenuhnya menguji logika model yang terpisah dari UI. Kontroler dan tampilan sangat tipis dan mudah diuji.

=== Menanggapi Dunk ===

Model dalam pola UI MVC (biasanya) bukan model objek bisnis. Itu hanya model untuk negara UI. Dalam aplikasi desktop, ini dapat menyimpan referensi ke beberapa model bisnis. Dalam aplikasi Web 2.0, ini adalah kelas Javascript yang menampung keadaan UI, dan berkomunikasi melalui AJAX ke server. Sangat penting untuk dapat menulis uji unit hands-off model negara UI, karena di situlah sebagian besar bug UI ditemukan. Tampilan dan pengontrol harus merupakan konektor yang sangat tipis.

kevin cline
sumber
1
Saya kira itu semua bermuara pada apa yang Anda yakini definisi MVC. Versi ini pasti mengikuti interpretasi MVC yang sangat, sangat ketat. Masalahnya adalah bahwa interpretasi yang ketat ini jarang menyediakan sistem yang berguna atau dapat dipertahankan dalam kehidupan nyata. Alasannya adalah bahwa hampir setiap kali Anda datang dengan elemen UI baru / cara melakukan sesuatu Anda harus mengubah model. Model kemudian menjadi berantakan dengan properti tidak berguna yang hanya relevan dengan UI. Ini tidak ada hubungannya dengan aplikasi yang Anda coba bangun tetapi hanya bagaimana Anda ingin mempresentasikan data ke operator. BURUK!
Dunk
kevin tolong letakkan tanggapan Anda di sini di kotak komentar, jadi mudah bagi kami untuk membalas Anda. Saya setuju dengan kamu. Tidak mungkin mempertahankan informasi antarmuka (UI) tanpa jenis struktur apa pun, tetapi nomenklatur "MODEL" mungkin membingungkan. Saya lebih suka mengatur hal-hal UI dalam paket dipertukarkan yang berbeda agar mudah melakukan apa yang dibicarakan @Dunk. Lihat jawaban saya.
Magno C
@ MagnoC: Saya mengedit dia menjawab sebagai respons terhadap Dunk karena saya pikir teks yang ditambahkan meningkatkan jawaban. Itulah yang dimaksud situs: pertanyaan dan jawaban. Model adalah istilah yang cukup umum, dan dalam pola MVC, itu berarti "model keadaan UI".
kevin cline
0

Logika bisnis lebih mirip If X then return InfoType.Y, maka UI akan menampilkan bidang berdasarkan hasil yang dikembalikan oleh domain.

// Controller method pseudocode
option changed routine

    get selected option

    get required info type from domain routine based on selected option

    display fields based on required info type

Jika UI memerlukan logika bisnis, maka delegasikan pilihan ke domain. UI hanya akan bertindak berdasarkan keputusan tersebut.

Yorro
sumber
0

Jika pengguna telah memilih opsi x maka aplikasi harus memungkinkannya untuk memberikan info untuk y, jika tidak maka ia harus menyediakan info z ".

Ada input yang memiliki nilai persyaratan berdasarkan persyaratan. Di sebagian besar lingkungan GUI, ada banyak pilihan tentang cara menangani input terutama pengaturan waktu. Opsi yang dipilih (dalam hal ini x) perlu diproses, jadi kirim ke pengontrol. Kirim ketika pengguna meninggalkan kolom input. Tunggu sampai mereka mengklik objek lain atau tekan save. Tidak masalah dengan logika bisnis. Dengan satu atau lain cara, pengontrol akan membuat keputusan dan perlu memberi tahu pandangan, "y diperlukan".

Bagaimana pandangan menginterpretasikan atau mengimplementasikan ini tidak terlalu penting dari sudut pandang logika bisnis. Buat bidang yang wajib diisi ya. Miliki pop-up atau tembak meriam dan beri tahu pengguna untuk memasukkan Anda atau hanya bersikap keras kepala dan jangan biarkan pengguna yang malang itu melakukan apa pun sampai ia mengetahui hal ini.

Dan hanya berpikir, semua ini mungkin terjadi karena controller mencoba untuk menyimpan dan tidak memasukkan nilai untuk bidang yang diperlukan dalam database dan murni menanggapi kesalahan database. Tidak masalah sejauh menyangkut pandangan.

Sesuatu seperti nilai yang diperlukan atau terbatas untuk input dapat ditangani di banyak tempat. Jika Anda "hanya" mengatasinya dalam tampilan, banyak pengembang akan melihat ini sebagai masalah ketika ada beberapa antarmuka pengguna. Inilah sebabnya mengapa logika bisnis dapat dibuat dan diuji tanpa banyak antarmuka pengguna atau bahkan database. Anda bahkan tidak perlu memiliki situs web.

JeffO
sumber