Struktur kacang pendukung JSF (praktik terbaik)


118

Saya berharap dalam posting ini, saya bisa mendapatkan pendapat orang-orang tentang praktik terbaik untuk antarmuka antara halaman JSF dan kacang pendukung.

Satu hal yang tidak pernah bisa saya atasi adalah struktur kacang pendukung saya. Selain itu, saya tidak pernah menemukan artikel bagus tentang masalah ini.

Properti apa yang dimiliki kacang pendukung? Kapan saat yang tepat untuk menambahkan lebih banyak properti ke kacang tertentu daripada membuat kacang baru dan menambahkan properti ke dalamnya? Untuk aplikasi sederhana, apakah masuk akal untuk hanya memiliki satu kacang pendukung untuk keseluruhan halaman, mengingat kerumitan yang terlibat dengan menyuntikkan satu kacang ke kacang lainnya? Haruskah kacang pendukung mengandung logika bisnis yang sebenarnya, atau haruskah itu benar-benar berisi data?

Jangan ragu untuk menjawab pertanyaan ini dan pertanyaan lain yang mungkin muncul.


Adapun untuk mengurangi kopling antara halaman JSF dan kacang pendukung, saya tidak pernah mengizinkan halaman JSF untuk mengakses properti properti kacang pendukung. Misalnya, saya tidak pernah mengizinkan sesuatu seperti:

<h:outputText value="#{myBean.anObject.anObjectProperty}" />

Saya selalu membutuhkan sesuatu seperti:

<h:outputText value="#{myBean.theObjectProperty}" />

dengan nilai kacang pendukung:

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}

Ketika saya mengulang koleksi, saya menggunakan kelas pembungkus untuk menghindari pengeboran ke objek dalam tabel data, misalnya.

Secara umum, pendekatan ini terasa "tepat" bagi saya. Ini menghindari keterkaitan antara tampilan dan data. Harap perbaiki saya jika saya salah.


Dapatkah Anda memberikan contoh untuk: Ketika saya mengulang koleksi, saya menggunakan kelas pembungkus untuk menghindari pengeboran ke dalam suatu objek dalam tabel data, misalnya.
Koray Tugay

2
Untuk informasi lebih lanjut, lihat jawaban BalusC di stackoverflow.com/questions/7223055/…
Zack Marrapese

Jawaban:


146

Anda mungkin ingin memeriksanya: membuat perbedaan antara berbagai jenis kacang yang dikelola JSF .

Berikut adalah deskripsi dari berbagai jenis kacang, sebagaimana didefinisikan dalam artikel di atas oleh Neil Griffin:

  • Model Managed-Bean : Biasanya cakupan sesi. Jenis kacang terkelola ini berpartisipasi dalam perhatian "Model" dari pola desain MVC. Saat Anda melihat kata "model" - pikirkan DATA. Model-bean JSF haruslah POJO yang mengikuti pola desain JavaBean dengan properti enkapsulasi getter / setter. Kasus penggunaan yang paling umum untuk model bean adalah menjadi entitas database, atau hanya mewakili satu set baris dari set hasil query database.
  • Backing Managed-Bean : Biasanya meminta ruang lingkup. Jenis kacang terkelola ini berpartisipasi dalam perhatian "Tampilan" dari pola desain MVC. Tujuan kacang pendukung adalah untuk mendukung logika UI, dan memiliki hubungan 1 :: 1 dengan tampilan JSF, atau bentuk JSF dalam komposisi Facelet. Meskipun biasanya memiliki properti gaya JavaBean dengan getter / setter terkait, ini adalah properti View - bukan dari model data aplikasi yang mendasarinya. Kacang pendukung JSF mungkin juga memiliki metode aksiListener JSF dan metode valueChangeListener.
  • Controller Managed-Bean : Biasanya meminta ruang lingkup. Jenis kacang terkelola ini berpartisipasi dalam perhatian "Pengontrol" dari pola desain MVC. Tujuan dari kacang pengontrol adalah untuk menjalankan beberapa jenis logika bisnis dan mengembalikan hasil navigasi ke penangan navigasi JSF. Kacang pengontrol JSF biasanya memiliki metode aksi JSF (dan bukan metode actionListener).
  • Support Managed-Bean : Biasanya cakupan sesi atau aplikasi. Jenis kacang ini "mendukung" satu atau lebih tampilan dalam perhatian "Tampilan" dari pola desain MVC. Kasus penggunaan tipikal menyediakan ArrayList ke JSF h: selectOneMenu daftar drop-down yang muncul di lebih dari satu tampilan JSF. Jika data dalam daftar dropdown khusus untuk pengguna, maka kacang akan disimpan dalam cakupan sesi. Namun, jika data berlaku untuk semua pengguna (seperti daftar dropdown provinsi), maka kacang akan disimpan dalam cakupan aplikasi, sehingga dapat di-cache untuk semua pengguna.
  • Utility Managed-Bean : Biasanya cakupan aplikasi. Jenis kacang ini menyediakan beberapa jenis fungsi "utilitas" untuk satu atau lebih tampilan JSF. Contoh yang bagus dari ini mungkin adalah file FileUpload yang dapat digunakan kembali di beberapa aplikasi web.

8
Ini adalah artikel yang bagus. Saya belum pernah melihatnya sebelumnya dan saya sangat senang Anda mempostingnya. Siapa pun yang menolak ini gila. Ini bukan spesifik iceFaces.
Zack Marrapese

2
Tautan ke artikel sebenarnya tampaknya hilang.
Bill Rosmus


10
Namun, saya tidak bisa menjelaskan bahwa jawaban ini saat ini di 71 suara positif. Siapa pun yang mengimplementasikan aplikasi JSF mereka sesuai aturan tersebut pasti setelah itu mengomel pada JSF sebagai kerangka kerja yang sangat buram dan aplikasi JSF mereka menjadi kekacauan kode yang besar dan mereka semua menyalahkan JSF itu sendiri alih-alih pendekatan buruk mereka sendiri berdasarkan pelajaran yang salah dan apa yang disebut. "praktik terbaik" dipelajari.
BalusC

apakah salah satu logika kacang ini dieksekusi di browser, bukan di server?
eskalera

14

Pertanyaan bagus. Saya sangat menderita dengan dilema yang sama ketika saya pindah ke JSF. Itu sangat tergantung pada aplikasi Anda. Saya dari dunia Java EE, jadi saya akan merekomendasikan untuk memiliki logika bisnis sesedikit mungkin dalam backing bean Anda. Jika logikanya murni terkait dengan presentasi halaman Anda, maka tidak masalah untuk memilikinya di kacang pendukung.

Saya yakin salah satu dari (banyak) kekuatan JSF sebenarnya adalah fakta bahwa Anda dapat mengekspos objek domain secara langsung pada kacang yang dikelola. Oleh karena itu, saya sangat menyarankan <:outputText value="#{myBean.anObject.anObjectProperty}" />pendekatan ini, jika tidak, Anda akhirnya akan membuat terlalu banyak pekerjaan untuk diri Anda sendiri dalam mengekspos setiap properti secara manual. Selain itu, akan sedikit berantakan saat memasukkan atau memperbarui data jika Anda merangkum semua properti. Ada situasi di mana satu objek domain mungkin tidak cukup. Dalam kasus tersebut saya menyiapkan ValueObject sebelum mengeksposnya pada kacang.

EDIT: Sebenarnya, jika Anda akan merangkum setiap properti objek yang ingin Anda ekspos, saya akan merekomendasikan Anda sebagai gantinya mengikat komponen UI ke kacang pendukung dan kemudian menyuntikkan konten langsung ke nilai komponen.

Dalam hal struktur kacang, titik balik bagi saya adalah ketika saya secara paksa mengabaikan semua hal yang saya ketahui tentang membangun aplikasi web dan mulai memperlakukannya sebagai aplikasi GUI. JSF banyak meniru Swing dan oleh karena itu praktik terbaik untuk mengembangkan aplikasi Swing sebagian besar juga berlaku untuk membangun aplikasi JSF.


Terima kasih atas wawasan Anda. Saya tidak pernah benar-benar melakukan banyak hal dalam aplikasi ayunan (selain proyek akademis dahulu kala). Apa sajakah prinsip yang baik dari aplikasi ayunan? Juga, mengapa berantakan saat memasukkan dan memperbarui nilai? sepertinya sama bagiku?
Zack Marrapese

5

Saya pikir yang paling penting dengan kacang pendukung Anda adalah memisahkan logika mereka. Jika Anda memiliki halaman depan untuk sistem CMS, saya akan melihatnya sebagai praktik yang buruk untuk meletakkan setiap bagian kode menjadi satu kacang karena:

  1. Kacang akan menjadi sangat besar pada akhirnya
  2. Lebih mudah bagi orang lain untuk menemukan apa yang mereka cari jika mereka memecahkan masalah halaman login, jika mereka dapat dengan mudah mencari file loginBean.java.
  3. Kadang-kadang Anda memiliki bagian-bagian kecil dari fungsionalitas yang jelas berbeda dari kode Anda yang lain, dengan memisahkan ini saya akan membayangkan Anda akan mempermudah diri Anda sendiri untuk mengembangkan kembali / memperluas kode ini menjadi sesuatu yang lebih besar, ketika Anda sudah memiliki kacang yang bagus dengan baik struktur.
  4. Memiliki 1 kacang besar, untuk melakukan semuanya, akan membuatnya lebih bergantung pada memori jika / ketika Anda harus melakukan deklarasi seperti ini MyBigBean bigBean = new MyBigBean (); daripada menggunakan funksjonality yang sebenarnya Anda butuhkan dengan melakukan LoginBean loginBean = new LoginBean (); (Koreksi saya jika saya salah di sini ???)
  5. Menurut pendapat saya, memisahkan biji Anda seperti memisahkan metode Anda. Anda tidak ingin 1 metode besar yang menjalankan lebih dari 100 baris, melainkan membaginya dengan metode baru yang menangani tugas khusus mereka.
  6. Ingat, kemungkinan besar orang lain selain Anda harus mengerjakan proyek JSF Anda juga.


Adapun kopling, saya tidak melihatnya sebagai masalah yang merepotkan untuk memungkinkan halaman JSF Anda mengakses terlalu properti dalam objek di backingbean Anda. Ini adalah dukungan yang dibangun ke dalam JSF, dan benar-benar membuatnya lebih mudah untuk membaca dan membangun imo. Anda semua sudah memisahkan logika MVC secara ketat. Dengan melakukan ini, Anda menghemat banyak baris dengan getter dan setter di backingbean Anda. Misalnya saya memiliki objek yang sangat besar yang diberikan kepada saya oleh layanan web, di mana saya perlu menggunakan beberapa properti dalam presentasi saya. Jika saya membuat pengambil / penyetel untuk setiap properti, kacang saya akan berkembang dengan setidaknya 100 baris lagi variabel dan metode untuk mendapatkan properti. Dengan menggunakan fungsionalitas JSF bawaan, waktu dan baris kode berharga saya dapat dihemat.

Hanya 2 sen saya tentang ini bahkan dengan pertanyaan yang sudah ditandai sebagai terjawab.


1
Namun, jika Anda memiliki objek besar yang duduk di bean Anda, dan Anda memiliki - katakanlah - 15 fungsi EL yang menggali ke dalam objek itu dari halaman JSF, Anda sekarang tidak hanya terikat ke bean, tetapi juga ke objek itu. Oleh karena itu, akan sulit untuk menghapus objek tersebut tanpa merusak UI.
Zack Marrapese

1
Tapi tidakkah kacang pendukung Anda akan terikat pada objek itu juga? Dan UI Anda terkait dengan kacang pendukung? Ketika Anda kemudian harus memodifikasinya, Anda harus mengubah semua getter / setter Anda di UI dan bean.
Chris Dale

4

Saya mungkin tidak menjawab setiap pertanyaan Anda, karena hanya sedikit yang tampaknya sangat bergantung pada kasus ke kasus.

  • Ini bagus untuk memiliki logika bisnis di kacang pendukung Anda. Tergantung dari mana Anda berasal. Jika Anda mempraktikkan desain yang digerakkan domain, Anda akan tergoda untuk memasukkan logika bisnis ke dalam kacang pendukung atau mungkin juga logika ketekunan. Mereka berpendapat bahwa mengapa objek begitu bodoh. Objek harus membawa tidak hanya keadaan tetapi juga perilaku. Di sisi lain jika Anda mempertimbangkan cara Java EE tradisional dalam melakukan sesuatu, Anda mungkin merasa seperti memiliki data di kacang pendukung Anda, yang juga bisa menjadi kacang entitas Anda, dan logika bisnis dan ketekunan lainnya di beberapa kacang sesi atau sesuatu. Itu juga bagus.

  • Tidak masalah untuk memiliki kacang pendukung tunggal untuk seluruh halaman. Saya tidak melihat ada masalah dengan ini sendirian. Ini mungkin tidak terlihat benar, tetapi itu tergantung pada kasusnya.

  • Pertanyaan Anda yang lain jauh lebih bergantung pada kasus yang Anda hadapi. Saya lebih suka menggunakan domain driven di sini, mungkin tepat untuk menambahkan properti ke yang sudah ada atau membuat kacang baru untuk itu. Mana yang lebih cocok. Saya tidak berpikir ada peluru perak untuk ini.

  • Properti mana yang dimiliki kacang pendukung. Nah, bukankah itu bergantung pada objek domain? Atau mungkin pertanyaannya tidak begitu jelas.

Selain itu, dalam contoh kode yang Anda berikan, saya tidak melihat manfaat yang besar.


jika - misalnya - kami mengubah dari menggunakan POJO buatan sendiri yang dibuat dengan kueri JDBC, ke entitas Hibernasi yang memiliki nama bidang yang sedikit berbeda, kami tidak hanya harus mengubah kacang pendukung. Kami juga harus mengubah halaman JSF. Tidak demikian halnya dengan contoh kode saya. Ganti saja buncisnya.
Zack Marrapese

Dalam hal ini Anda dapat membuat kacang pendukung Anda, entitas. maka Anda hanya perlu mengubah halaman JSF. Atau itu tergantung mengapa Anda mengubah nama properti? itu hanya akan masuk akal ketika Anda mengganti nama bidang agar sesuai dengan nama kolom database Anda. Tapi itu kasus yang berbeda.
Adeel Ansari

4

Saya tidak perlu menyimpan hanya satu kacang pendukung per halaman. Itu tergantung pada fungsionalitas tetapi sebagian besar waktu saya memiliki satu kacang per halaman karena kebanyakan satu halaman menangani satu fungsi. Misalnya pada halaman saya memiliki link register (saya akan link dengan RegisterBean) dan link keranjang belanja (ShoopingBasketBean).

Saya menggunakan <: outputText value = "# {myBean.anObject.anObjectProperty}" /> ini karena saya biasanya menyimpan kacang pendukung sebagai kacang tindakan yang menyimpan objek data. Saya tidak ingin menulis pembungkus di kacang pendukung saya untuk mengakses properti objek data saya.


0

Saya suka menguji kode bisnis tanpa View, jadi saya menganggap BackingBeans sebagai antarmuka dari kode View ke Model. Saya tidak pernah meletakkan aturan atau proses apa pun di BackingBean. Kode itu masuk ke Layanan atau Pembantu, memungkinkan penggunaan kembali.

Jika Anda menggunakan validator, keluarkan dari BackingBean dan referensikan dari metode validasi Anda.

Jika Anda mengakses DAO untuk mengisi Selects, Radio, Checkboxes, lakukan itu selalu dari BackingBean.

Percayalah padaku!. Anda dapat memasukkan JavaBean ke dalam BackingBean, tetapi coba masukkan BackingBean ke yang lain. Anda akan segera berada dalam mimpi buruk tentang pemeliharaan dan pemahaman kode.

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.