Haruskah ekspresi EL yang rumit digantikan oleh satu pengambil javabean?


10

Di JSF jika saya memiliki komponen yang secara kondisional merender berdasarkan sejumlah variabel, apa cara optimal untuk menangani pernyataan render ... apakah logika harus hidup dalam deklarasi komponen atau dalam beberapa bentuk kelas pembantu?

Pakan teks hanya ditampilkan ketika seekor binatang adalah gajah atau anjing dan hewan itu tidak bisu.

Pilihan 1:

Implementasi dalam tampilan:

<h:outputText id="text" value="woof" 
  rendered="#{animal.type == 'elephant' 
                  or animal.type == 'dog' and not(animal.mute)}"/>

atau Opsi 2:

Enkapsulasi:

<h:outputText id="text" value="woof" rendered="#{animal.barkingAnimal}"/>

dengan implementasi:

public class Animal {
     public boolean isBarkingAnimal() {
         return ("dog".equals(getType()) || "elephant".equals(getType())) && !isMute();
     }
...

Jadi keduanya berfungsi ... tapi mana cara yang tepat untuk menangani skenario?


Untuk contoh khusus itu saya akan menggunakan el. Tampaknya hanya untuk melihat data terkait. Jika Anda memiliki beberapa logika dalam kode java Anda karena barking animalssaya akan memanggil metode itu, karena sudah ada. Jika ini tampilan logika yang Anda gunakan di banyak situs, Anda bisa membangun fungsi el dari situ.

The Ekspresi Bahasa awalnya disebut sederhana Kemungkinan Bahasa Ekspresi sehingga mungkin mengisyaratkan penggunaan yang dimaksudkan. Pandangan saya sendiri: jika ini pandangan logika, EL mungkin sesuai; jika itu logika bisnis, itu tidak.
McDowell

Jawaban:


5

Dalam kebanyakan kasus, ini hanyalah masalah selera. Jika kekhawatiran Anda hanya menggunakan kembali kondisi tersebut, Anda dapat melakukannya:

<ui:param name="animalCanBark" value="#{animal.type == 'elephant' 
              or animal.type == 'dog' and not(animal.mute)}" />
...
<h:outputText id="text" value="woof" rendered="#{animalCanBark}"/>

Ini sering berguna ketika ungkapan yang Anda perlu tulis melibatkan lebih dari satu objek, katakan:

<ui:param name="showBarking" value="#{animal.type == 'elephant'
              and not facesContext.validationFailed" />

Saya pikir banyak orang lebih suka menulis jenis logika ini di Jawa daripada di EL karena kompiler Java dapat melakukan pengecekan tipe dalam kode Java (juga, sebagian besar IDE memiliki pelengkapan otomatis yang lebih baik untuk Java daripada untuk file .XHTML), yang merupakan masalah. untuk beberapa.

Karena itu, jika ini merupakan informasi tentang model yang suatu hari nanti dapat digunakan di tempat lain (bukan hanya halaman Facelets / JSF lain), itu akan menjadi alasan yang baik untuk melakukannya dalam kode Java Anda. Pada contoh yang Anda berikan, metode ini isBarkingAnimal()memberikan beberapa informasi tentang model ( Animal), yang suatu hari nanti mungkin berguna ketika objek lain (bukan hanya halaman Facelets lainnya) perlu tahu apakah ada gonggongan binatang yang diberikan. Jadi, saya mungkin akan pergi dengan itu.


3

Sebagai aturan praktis, cobalah untuk menjaga file .xhtml sebebas mungkin, sehingga hanya menangani presentasi. Jadi, jelas untuk opsi 2.


2
Apakah ini logika yang perlu diperhatikan oleh model? Jika digunakan lebih dari sekali, mengapa aliasing menggunakan <c:set>atau <ui:param>tidak menjadi pilihan?

Contoh itu tidak memiliki logika model di belakangnya. Anda akan menggeser tampilan logika ke model logika, yang menghasilkan kode java yang bahkan tidak dipanggil dalam java. Jika kelas Animalberada di lingkungan lain (jarak jauh) atau programer hanya tidak relevan untuk itu.

1

Secara pribadi, saya akan menggunakan Opsi # 2. Meskipun saya tahu sangat mungkin untuk menyelesaikan masalah menggunakan EL dan mendapatkan sedikit penggunaan kembali di seluruh dokumen xhtml menggunakan fungsi atau ui: params tampaknya benar-benar kurang portabilitas, rawatan dan testabilitas dari implementasi Java bean.

Jika pengembang fasih dalam EL dan Java dan memiliki kedua xhtml dan kacang Jawa, tampaknya tidak masuk akal untuk menggunakan EL untuk melakukan evaluasi bersyarat APAPUN dengan ukuran> 1.

Tampaknya ada terlalu banyak manfaat untuk diterapkan di sisi Jawa:

  • Kemampuan untuk bersandar pada IDE + compiler
  • Gunakan konstanta atau enum (untuk "anjing" dan "kulit"), kemungkinan mereka sedang digunakan di tempat lain dalam kode untuk perbandingan juga ... jika nilai String berubah itu benar-benar menyenangkan harus secara manual mengganti setiap kejadian di seluruh basis kode
  • Daripada harus menavigasi ke halaman yang bersangkutan dengan data yang sesuai, saya dapat menggunakan logika menggunakan unit test

Salah satu argumen utama yang saya dengar (di luar Stack) yang mendukung Opsi 1 adalah:

"Jauh lebih mudah untuk melihat kapan suatu komponen merender jika Anda tetap menggunakan logika ini."

Saya telah menemukan bahwa ini mungkin menjadi kasus untuk aplikasi pada tahap awal kehidupannya di mana beratnya lebih ringan dan tidak terlalu rumit. Namun menerapkan praktik ini pada skala yang lebih besar dan sebagai aplikasi yang lebih kecil matang dapat menyebabkan sarang tikus kondisi dan menjadi mimpi buruk untuk dipertahankan. Berikut adalah beberapa contoh yang mirip dengan apa yang saya lihat di alam liar:

<h:outputText value="grrr" 
    render="#{animal.type == 'dog' or animal.type == 'cat' or animal.type == 'horse' 
        or animal.type == 'pony' or animal.type == 'mule' or animal.type == 'lion'
        or animal.type == 'tiger' or (animal.type == 'bird' 
        and animal.subType == 'macaw') or .... continue this for another line or two}"
/>

Atau favorit saya, menggunakan beberapa komponen dengan kondisi render yang eksklusif satu sama lain untuk mewakili nilai yang berbeda yang dapat ditampilkan:

<h:outputText value="grr" render="#{theMonstrosityFromPreviousExample} />
<h:outputText value="cry" 
    render="#{animal.type == 'human' and animal.subType == 'baby'}" />
<h:outputText value="yo" 
    render="#{animal.type == 'human' and animal.subType == 'teenager'}" />
<h:outputText value="hello" 
    render="#{animal.type == 'human' and animal.subType == 'adult'}"/>

Bisakah hingga 4 teks ditampilkan sekaligus? Pada pandangan pertama Anda tidak tahu, pemeriksaan setiap kondisi akan diperlukan. Sebagai catatan saya menyadari contoh ini juga desain yang buruk, karena ini dapat dimasukkan ke dalam ac: pilih ... tapi saya pernah melihat ini sebelumnya.

Pada akhirnya, ini masih secara teoritis 'melihat' logika karena menentukan apa yang sebenarnya ditampilkan sehingga ada argumen konseptual yang harus dijalani dalam xhtml. Masalah yang saya temukan adalah bahwa termasuk logika seperti ini dalam template tampilan dapat membuat tata letak lebih sulit untuk dipahami dalam jangka panjang dan saya belum melihat bahwa metode penyelesaian masalah ini memiliki manfaat nyata dibandingkan menggunakan Java implementasi kacang.

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.