โครงสร้างถั่วสำรอง JSF (แนวทางปฏิบัติที่ดีที่สุด)


118

ฉันหวังว่าในโพสต์นี้ฉันจะได้รับความคิดเห็นของผู้คนเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดสำหรับอินเทอร์เฟซระหว่างหน้า JSF และถั่วสำรอง

สิ่งหนึ่งที่ฉันไม่สามารถทำได้คือโครงสร้างของถั่วสำรองของฉัน นอกจากนี้ฉันไม่เคยพบบทความที่ดีเกี่ยวกับเรื่องนี้

คุณสมบัติอะไรที่อยู่ในถั่วสำรอง? เมื่อใดจึงเหมาะสมที่จะเพิ่มคุณสมบัติเพิ่มเติมให้กับถั่วที่กำหนดเมื่อเทียบกับการสร้าง bean ใหม่และเพิ่มคุณสมบัติลงไป สำหรับการใช้งานที่เรียบง่ายควรมีแบ็คกิ้งบีนเพียงอันเดียวสำหรับทั้งหน้าโดยพิจารณาถึงความซับซ้อนที่เกี่ยวข้องกับการฉีดถั่วหนึ่งเข้าไปในอีกอันหนึ่ง backing bean ควรมีตรรกะทางธุรกิจจริงหรือไม่หรือควรมีข้อมูลอย่างเคร่งครัด?

อย่าลังเลที่จะตอบคำถามเหล่านี้และคำถามอื่น ๆ ที่อาจเกิดขึ้น


สำหรับการลดการเชื่อมต่อระหว่างเพจ JSF และแบ็คกิ้งบีนฉันไม่เคยอนุญาตให้เพจ JSF เข้าถึงคุณสมบัติของแบ็คกิ้งบีน ตัวอย่างเช่นฉันไม่อนุญาตบางสิ่งเช่น:

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

ฉันต้องการบางสิ่งบางอย่างเช่น:

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

ด้วยค่าถั่วสำรองที่:

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

เมื่อฉันวนซ้ำคอลเลกชันฉันใช้คลาส wrapper เพื่อหลีกเลี่ยงการเจาะลึกลงไปในวัตถุในตารางข้อมูลเป็นต้น

โดยทั่วไปแนวทางนี้ให้ความรู้สึก "ถูกต้อง" สำหรับฉัน หลีกเลี่ยงการมีเพศสัมพันธ์ระหว่างมุมมองและข้อมูล กรุณาแก้ไขฉันถ้าฉันผิด


คุณสามารถยกตัวอย่างได้ไหม: เมื่อฉันวนรอบคอลเลกชันฉันใช้คลาส wrapper เพื่อหลีกเลี่ยงการเจาะลึกลงไปในวัตถุในตารางข้อมูลเป็นต้น
Koray Tugay

2
สำหรับข้อมูลเพิ่มเติมโปรดดูคำตอบของ BalusC ที่stackoverflow.com/questions/7223055/…
Zack Marrapese

คำตอบ:


146

คุณอาจต้องการที่จะตรวจสอบนี้ทำให้ความแตกต่างระหว่างชนิดที่แตกต่างกันของถั่ว JSF การจัดการ

นี่คือคำอธิบายของถั่วประเภทต่างๆตามที่กำหนดไว้ในบทความข้างต้นโดย Neil Griffin:

  • Model Managed-Bean : ปกติขอบเขตเซสชัน ถั่วที่มีการจัดการประเภทนี้มีส่วนร่วมในข้อกังวล "Model" ของรูปแบบการออกแบบ MVC เมื่อคุณเห็นคำว่า "model" - ให้คิดว่า DATA JSF model-bean ควรเป็น POJO ที่เป็นไปตามรูปแบบการออกแบบ JavaBean ที่มีคุณสมบัติการห่อหุ้ม getters / setters กรณีการใช้งานที่พบบ่อยที่สุดสำหรับ model bean คือการเป็นเอนทิตีฐานข้อมูลหรือเพื่อแสดงชุดของแถวจากชุดผลลัพธ์ของแบบสอบถามฐานข้อมูล
  • Backing Managed-Bean : โดยปกติขอบเขตการร้องขอ ถั่วที่มีการจัดการประเภทนี้มีส่วนร่วมใน "มุมมอง" ของรูปแบบการออกแบบ MVC จุดประสงค์ของ backing-bean คือการสนับสนุนตรรกะ UI และมีความสัมพันธ์แบบ 1 :: 1 กับมุมมอง JSF หรือรูปแบบ JSF ในองค์ประกอบของ Facelet แม้ว่าโดยทั่วไปจะมีคุณสมบัติสไตล์ JavaBean พร้อมด้วย getters / setters ที่เกี่ยวข้อง แต่คุณสมบัติเหล่านี้เป็นคุณสมบัติของ View - ไม่ใช่ของโมเดลข้อมูลแอ็พพลิเคชันพื้นฐาน JSF backing-beans อาจมีวิธี JSF actionListener และ valueChangeListener
  • Controller Managed-Bean : ขอบเขตการร้องขอตามปกติ ถั่วที่มีการจัดการประเภทนี้มีส่วนร่วมในข้อกังวล "คอนโทรลเลอร์" ของรูปแบบการออกแบบ MVC วัตถุประสงค์ของ Controller bean คือการดำเนินการตรรกะทางธุรกิจบางประเภทและส่งคืนผลลัพธ์การนำทางไปยังตัวจัดการการนำทาง JSF โดยทั่วไป JSF controller-beans มีวิธีการดำเนินการ JSF (และไม่ใช่วิธีการ actionListener)
  • รองรับ Managed-Bean : ปกติเซสชันหรือขอบเขตแอปพลิเคชัน ถั่วชนิดนี้ "สนับสนุน" มุมมองอย่างน้อยหนึ่งมุมมองในข้อกังวล "มุมมอง" ของรูปแบบการออกแบบ MVC กรณีการใช้งานทั่วไปคือการส่ง ArrayList ไปยัง JSF h: รายการแบบเลื่อนลง selectOneMenu ที่ปรากฏในมุมมอง JSF มากกว่าหนึ่งมุมมอง หากข้อมูลในรายการดรอปดาวน์เป็นข้อมูลเฉพาะสำหรับผู้ใช้ bean จะถูกเก็บไว้ในขอบเขตเซสชัน อย่างไรก็ตามหากข้อมูลใช้กับผู้ใช้ทั้งหมด (เช่นรายการแบบเลื่อนลงของจังหวัด) bean จะถูกเก็บไว้ในขอบเขตแอปพลิเคชันเพื่อให้สามารถแคชสำหรับผู้ใช้ทั้งหมดได้
  • ยูทิลิตี้ Managed-Bean : โดยปกติขอบเขตการใช้งาน ถั่วชนิดนี้มีฟังก์ชัน "ยูทิลิตี้" บางประเภทให้กับมุมมอง JSF ตั้งแต่หนึ่งมุมมองขึ้นไป ตัวอย่างที่ดีอาจเป็น FileUpload bean ที่สามารถนำมาใช้ซ้ำในเว็บแอปพลิเคชันต่างๆ

8
นี่เป็นบทความที่ยอดเยี่ยม ฉันไม่เคยเห็นมาก่อนและดีใจอย่างแน่นอนที่คุณโพสต์ ใครโหวตลงนี้เป็นบ้า ไม่ใช่เฉพาะ IceFaces
Zack Marrapese

2
ดูเหมือนว่าลิงก์ไปยังบทความจริงจะหายไป
Bill Rosmus

สามารถดูสำเนาได้ที่นี่
ChrLipp

10
ฉันยังไม่เข้าใจว่าคำตอบนี้อยู่ที่ 71 upvotes ใครก็ตามที่ติดตั้งแอปพลิเคชัน JSF ตามกฎเหล่านั้นจะต้องพูดจาโผงผางอย่างไม่ต้องสงสัยในภายหลังว่า JSF เป็นเฟรมเวิร์กที่ทึบมากและแอปพลิเคชัน JSF ของพวกเขาเป็นระเบียบรหัสขนาดใหญ่และพวกเขาทั้งหมดตำหนิ JSF เองแทนที่จะเป็นแนวทางที่ไม่ดีของพวกเขาเองจากบทเรียนที่ไม่ถูกต้องและที่เรียกว่า "แนวทางปฏิบัติที่ดีที่สุด" ได้เรียนรู้
BalusC

ตรรกะของถั่วเหล่านี้ถูกดำเนินการในเบราว์เซอร์แทนที่จะเป็นในเซิร์ฟเวอร์หรือไม่?
eskalera

14

คำถามที่ดี ฉันทุกข์ทรมานมากกับปัญหาเดียวกันเมื่อฉันย้ายไปที่ JSF ขึ้นอยู่กับใบสมัครของคุณจริงๆ ฉันมาจากโลก Java EE ดังนั้นฉันขอแนะนำให้มีตรรกะทางธุรกิจน้อยที่สุดในถั่วสำรองของคุณให้มากที่สุด หากตรรกะเกี่ยวข้องกับการนำเสนอเพจของคุณอย่างหมดจดคุณควรมีไว้ในแบ็คกิ้งบีน

ฉันเชื่อว่าจุดแข็งอย่างหนึ่ง (หลาย ๆ ) ของ JSF คือความจริงที่ว่าคุณสามารถเปิดเผยวัตถุโดเมนบนถั่วที่มีการจัดการได้โดยตรง ดังนั้นฉันจึงขอแนะนำ<:outputText value="#{myBean.anObject.anObjectProperty}" />แนวทางนี้เป็นอย่างยิ่งมิฉะนั้นคุณจะทำงานหนักเกินไปสำหรับตัวเองในการเปิดเผยทรัพย์สินแต่ละรายการด้วยตนเอง นอกจากนี้การแทรกหรืออัปเดตข้อมูลจะเป็นเรื่องยุ่งยากหากคุณห่อหุ้มคุณสมบัติทั้งหมดไว้ มีสถานการณ์ที่อ็อบเจ็กต์โดเมนเดียวอาจไม่เพียงพอ ในกรณีเหล่านี้ฉันเตรียมValueObjectก่อนที่จะเปิดเผยบนถั่ว

แก้ไข: จริงๆแล้วถ้าคุณจะห่อหุ้มทุกคุณสมบัติของวัตถุที่คุณต้องการเปิดเผยฉันขอแนะนำให้คุณผูกคอมโพเนนต์ UI กับถั่วสำรองแทนแล้วจึงฉีดเนื้อหาลงในค่าของส่วนประกอบโดยตรง

ในแง่ของโครงสร้างบีนจุดเปลี่ยนสำหรับฉันคือเมื่อฉันละเลยทุกสิ่งที่ฉันรู้เกี่ยวกับการสร้างเว็บแอปพลิเคชันและเริ่มใช้เป็นแอปพลิเคชัน GUI แทน JSF เลียนแบบ Swing เป็นจำนวนมากดังนั้นแนวทางปฏิบัติที่ดีที่สุดสำหรับการพัฒนาแอปพลิเคชัน Swing ส่วนใหญ่จะใช้กับการสร้างแอปพลิเคชัน JSF ด้วย


ขอบคุณสำหรับข้อมูลเชิงลึก ฉันไม่เคยทำอะไรมากในการประยุกต์ใช้งานวงสวิง (นอกเหนือจากโครงการทางวิชาการเมื่อนานมาแล้ว) หลักการใช้งานวงสวิงที่ดีมีอะไรบ้าง? นอกจากนี้ทำไมการแทรกและอัปเดตค่าจึงเป็นเรื่องยุ่งยาก ดูเหมือนกันกับฉันไหม
Zack Marrapese

5

ฉันคิดว่าสิ่งที่สำคัญที่สุดสำหรับถั่วสำรองของคุณคือการแยกตรรกะของพวกเขาออกจากกัน หากคุณมีหน้าแรกสำหรับระบบ CMS ฉันจะเห็นว่าเป็นแนวทางปฏิบัติที่ไม่ดีในการใส่โค้ดทุกชิ้นลงใน bean เดียวเนื่องจาก:

  1. ถั่วจะเปลี่ยนเป็นขนาดใหญ่มากในที่สุด
  2. มันง่ายกว่าสำหรับคนอื่นในการค้นหาสิ่งที่พวกเขากำลังมองหาหากพวกเขากำลังแก้ไขปัญหาหน้าล็อกอินหากพวกเขาสามารถค้นหาไฟล์ loginBean.java ได้อย่างง่ายดาย
  3. บางครั้งคุณมีฟังก์ชันการทำงานเล็ก ๆ น้อย ๆ ที่แตกต่างอย่างชัดเจนจากส่วนที่เหลือของโค้ดของคุณโดยการแยกสิ่งนี้ฉันคิดว่าคุณจะช่วยให้คุณสามารถพัฒนา / ขยายโค้ดนี้ใหม่ให้ใหญ่ขึ้นได้ง่ายขึ้นเมื่อคุณมีถั่วที่ดีอยู่แล้ว โครงสร้าง.
  4. การมีถั่วขนาดใหญ่ 1 เมล็ดจะทำให้หน่วยความจำขึ้นอยู่กับว่า / เมื่อใดที่คุณต้องทำการประกาศเช่นนี้ MyBigBean bigBean = MyBigBean ใหม่ (); แทนที่จะใช้ funksjonality ที่คุณต้องการจริงๆโดยทำ LoginBean loginBean = new LoginBean (); (แก้ไขฉันถ้าฉันผิดที่นี่ ???)
  5. ในความคิดของฉันการแยกถั่วของคุณก็เหมือนกับการแยกวิธีของคุณ คุณไม่ต้องการวิธีการใหญ่ 1 วิธีที่ใช้งานได้มากกว่า 100 บรรทัด แต่แยกออกเป็นวิธีการใหม่ที่จัดการกับงานเฉพาะของพวกเขา
  6. โปรดจำไว้ว่าคนส่วนใหญ่ที่ไม่ใช่คุณจะต้องทำงานในโครงการ JSF ของคุณด้วย


สำหรับการมีเพศสัมพันธ์ฉันไม่เห็นว่ามันเป็นปัญหาที่ยุ่งยากในการอนุญาตให้หน้า JSF ของคุณเข้าถึงคุณสมบัติในวัตถุในถั่วสำรองของคุณมากเกินไป นี่คือการสนับสนุนที่สร้างขึ้นใน JSF และช่วยให้อ่านและสร้าง imo ได้ง่ายขึ้น คุณแยกตรรกะ MVC อย่างเคร่งครัด ด้วยการทำเช่นนี้คุณจะช่วยตัวเองได้เป็นจำนวนมากด้วย getters และ setters ใน backingbean ของคุณ ตัวอย่างเช่นฉันมีวัตถุชิ้นใหญ่ที่มอบให้โดยบริการบนเว็บซึ่งฉันต้องใช้คุณสมบัติบางอย่างในการนำเสนอของฉัน ถ้าฉันจะสร้าง getter / setter สำหรับแต่ละคุณสมบัติ bean ของฉันจะขยายด้วยตัวแปรและวิธีการรับ propeties อย่างน้อย 100 บรรทัด ด้วยการใช้ฟังก์ชัน JSF ที่สร้างขึ้นในเวลาและบรรทัดรหัสอันมีค่าของฉันจึงหมดไป

เพียง 2 เซ็นต์ของฉันเกี่ยวกับเรื่องนี้แม้ว่าคำถามจะถูกทำเครื่องหมายว่าตอบแล้วก็ตาม


1
อย่างไรก็ตามหากคุณมีวัตถุขนาดใหญ่ที่นั่งอยู่ในถั่วของคุณและคุณมี - พูด - 15 ฟังก์ชัน EL ที่ขุดเข้าไปในวัตถุนั้นจากหน้า JSF ตอนนี้คุณไม่ได้เชื่อมโยงกับถั่วเท่านั้น แต่ยังรวมกับวัตถุนั้นด้วย ดังนั้นจึงเป็นการยากที่จะลบวัตถุนั้นโดยไม่ทำลาย UI
Zack Marrapese

1
แต่ถั่วสำรองของคุณจะไม่ผูกติดกับวัตถุนั้นด้วยหรือ? และ UI ของคุณเชื่อมโยงกับถั่วสำรองหรือไม่? เมื่อคุณต้องแก้ไขคุณจะต้องเปลี่ยน getters / setters ทั้งหมดของคุณทั้งใน UI และ bean
Chris Dale

4

ฉันอาจไม่ตอบทุกคำถามของคุณเพราะมีเพียงไม่กี่คำถามที่ขึ้นอยู่กับแต่ละกรณี

  • นี่เป็นเรื่องปกติที่จะมีตรรกะทางธุรกิจในถั่วสำรองของคุณ ขึ้นอยู่กับว่าคุณมาจากไหน หากคุณกำลังฝึกฝนการออกแบบที่ขับเคลื่อนด้วยโดเมนคุณจะถูกล่อลวงให้รวมตรรกะทางธุรกิจไว้ในถั่วสำรองหรืออาจเป็นตรรกะที่คงอยู่ด้วยเช่นกัน พวกเขาเถียงว่าทำไมวัตถุโง่ ๆ ออบเจ็กต์ไม่ควรมีเพียงสถานะ แต่พฤติกรรมด้วย ในทางกลับกันถ้าคุณพิจารณาวิธี Java EE แบบดั้งเดิมในการทำสิ่งต่างๆคุณอาจรู้สึกเหมือนมีข้อมูลอยู่ในถั่วสำรองของคุณซึ่งอาจเป็นเอนทิตีบีนของคุณและตรรกะทางธุรกิจและการคงอยู่อื่น ๆ ในบางเซสชันบีนหรือบางอย่าง นั่นก็ดีเหมือนกัน

  • ดีอย่างสมบูรณ์แบบที่จะมีถั่วสำรองสำหรับทั้งหน้า ฉันไม่เห็นปัญหาใด ๆ กับเรื่องนี้เพียงอย่างเดียว สิ่งนี้อาจดูไม่ถูกต้อง แต่ขึ้นอยู่กับกรณี

  • คำถามอื่น ๆ ของคุณขึ้นอยู่กับกรณีที่คุณมีอยู่ในมือมากกว่า ฉันต้องการไปที่โดเมนขับเคลื่อนที่นี่อาจเป็นการเหมาะสมที่จะเพิ่มคุณสมบัติให้กับสิ่งที่มีอยู่หรือสร้าง bean ใหม่สำหรับสิ่งนั้น ซึ่งเคยเหมาะสมกว่า ฉันไม่คิดว่าจะมีกระสุนเงินสำหรับสิ่งนี้

  • คุณสมบัติใดเป็นของถั่วสำรอง มันไม่ได้ขึ้นอยู่กับวัตถุโดเมนเหรอ? หรืออาจจะเป็นคำถามที่ไม่ชัดเจนนัก

ยิ่งไปกว่านั้นในตัวอย่างโค้ดของคุณฉันไม่เห็นประโยชน์อะไรมากมาย


ถ้า - ตัวอย่าง - เราจะเปลี่ยนจากการใช้ POJO ที่ผลิตเองที่บ้านที่สร้างด้วยแบบสอบถาม JDBC เป็นเอนทิตีไฮเบอร์เนตที่มีชื่อฟิลด์ต่างกันเล็กน้อยเราจะต้องไม่เพียง แต่เปลี่ยนถั่วสำรอง เราจะต้องเปลี่ยนหน้า JSF ด้วย ไม่เป็นเช่นนั้นกับตัวอย่างรหัสของฉัน เพียงแค่เปลี่ยนถั่ว
Zack Marrapese

ในกรณีนั้นคุณสามารถสร้างถั่วสำรองเอนทิตีได้ จากนั้นคุณก็ต้องเปลี่ยนหน้า JSF หรือขึ้นอยู่กับว่าทำไมคุณถึงเปลี่ยนชื่อคุณสมบัติ? ซึ่งจะสมเหตุสมผลก็ต่อเมื่อคุณเปลี่ยนชื่อฟิลด์ให้ตรงกับชื่อคอลัมน์ฐานข้อมูลของคุณ แต่นั่นเป็นกรณีที่แตกต่างกันโดยสิ้นเชิง
Adeel Ansari

4

ฉันไม่จำเป็นต้องเก็บถั่วสำรองเพียงอันเดียวต่อหน้า ขึ้นอยู่กับฟังก์ชันการทำงาน แต่ส่วนใหญ่ฉันมีหนึ่ง bean ต่อหน้าเนื่องจากส่วนใหญ่หนึ่งเพจจัดการกับฟังก์ชันเดียว ตัวอย่างเช่นในหน้าฉันมีลิงก์ลงทะเบียน (ฉันจะเชื่อมโยงกับ RegisterBean) และลิงก์ตะกร้าสินค้า (ShoopingBasketBean)

ฉันใช้ <: outputText value = "# {myBean.anObject.anObjectProperty}" /> ตามปกติฉันจะเก็บถั่วสำรองไว้เป็นถั่วการดำเนินการซึ่งเก็บวัตถุข้อมูลไว้ ฉันไม่ต้องการเขียน wrapper ใน backing bean เพื่อเข้าถึงคุณสมบัติของออบเจ็กต์ข้อมูลของฉัน


0

ฉันชอบทดสอบรหัสธุรกิจโดยไม่ใช้ View ดังนั้นฉันจึงถือว่า BackingBeans เป็นอินเทอร์เฟซจาก View to Model code ฉันไม่เคยใส่กฎหรือกระบวนการใด ๆ ใน BackingBean รหัสนั้นจะไปอยู่ใน Services หรือ Helpers ซึ่งอนุญาตให้ใช้ซ้ำได้

หากคุณใช้ตัวตรวจสอบความถูกต้องให้นำออกจาก BackingBean ของคุณและอ้างอิงจากวิธีการตรวจสอบของคุณ

หากคุณเข้าถึง DAO เพื่อเติม Selects, Radios, Checkboxes ให้ทำเช่นนั้นเสมอจาก BackingBean

เชื่อฉัน!. คุณฉีด JavaBean ลงใน BackingBean ได้ แต่ลองฉีด BackingBean เข้าไปในอีกอันหนึ่ง คุณจะพบกับความเลวร้ายของการบำรุงรักษาและการทำความเข้าใจโค้ดในไม่ช้า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.