ฉันจะแยกส่วนติดต่อผู้ใช้ออกจากตรรกะทางธุรกิจในขณะที่ยังคงรักษาประสิทธิภาพได้อย่างไร


19

สมมติว่าฉันต้องการที่จะแสดงรูปแบบที่แสดงถึง 10 วัตถุที่แตกต่างกันใน combobox ตัวอย่างเช่นฉันต้องการให้ผู้ใช้เลือกหนึ่งแฮมเบอร์เกอร์จาก 10 เมนูที่มีมะเขือเทศ

เนื่องจากฉันต้องการแยก UI และตรรกะฉันจะต้องผ่านแบบฟอร์มการเป็นตัวแทนสตริงของแฮมเบอร์เกอร์เพื่อแสดงบน Combobox มิฉะนั้น UI จะต้องขุดลงในช่องวัตถุ จากนั้นผู้ใช้จะเลือกแฮมเบอร์เกอร์จากคอมโบบ็อกซ์แล้วส่งกลับไปที่คอนโทรลเลอร์ ตอนนี้ผู้ควบคุมจะต้องหาแฮมเบอร์เกอร์อีกครั้งโดยอ้างอิงจากการแทนค่าสตริงที่ใช้โดยแบบฟอร์ม (อาจเป็น ID?)

มันไม่มีประสิทธิภาพอย่างไม่น่าเชื่อใช่หรือไม่? คุณมีวัตถุที่คุณต้องการเลือกแล้ว หากคุณส่งแบบฟอร์มไปยังวัตถุทั้งหมดแล้วส่งคืนวัตถุเฉพาะคุณจะไม่ต้อง refind อีกครั้งในภายหลังเนื่องจากแบบฟอร์มส่งคืนการอ้างอิงไปยังวัตถุนั้นแล้ว

ยิ่งกว่านั้นถ้าฉันผิดและคุณควรส่งวัตถุทั้งหมดไปยังแบบฟอร์มฉันจะแยก UI ออกจากตรรกะได้อย่างไร


มันจะไม่มีประสิทธิภาพในทางใด? ในทุกกรณีคุณต้องแสดงการแทนสตริงให้กับผู้ใช้และแมปคำตอบของเขากับวัตถุต้นฉบับ
Simon Bergot

ปัญหาคือว่าในการทำงานกับวัตถุดังกล่าวฉันต้องดึงมันอีกครั้งหลังจากที่ผู้ใช้หยิบมัน
Uri

คำตอบ:


34

ก่อนอื่นตัวอย่างที่คุณให้นั้นไม่มีประสิทธิภาพอย่างไม่น่าเชื่อ มันไม่มีประสิทธิภาพเพียงเล็กน้อยเท่านั้น ความไร้ประสิทธิภาพต่ำกว่าระดับที่เข้าใจได้ แต่ในกรณีใด ๆ มาต่อกับคำถาม

วิธีที่ผมเข้าใจมันเมื่อเราพูดถึงการแยกของ UI และ Logicเราหมายถึงการหลีกเลี่ยงการมีเพศสัมพันธ์อย่างใกล้ชิด

Close couplingหมายถึงสถานการณ์ที่ UI รู้ (และเรียกใช้) ตรรกะและตรรกะรู้ (และเรียกใช้) UI เพื่อหลีกเลี่ยงการมีเพศสัมพันธ์อย่างใกล้ชิดไม่จำเป็นต้องหันไปใช้ข้อต่อร่วมกันโดยสิ้นเชิง (นั่นคือสิ่งที่คุณดูเหมือนจะมีจุดมุ่งหมายด้วยการทำลายอินเทอร์เฟซระหว่างพวกเขาลงไปที่ส่วนต่อประสานสายอักขระที่ใช้ร่วมกันน้อยที่สุด) สิ่งหนึ่งที่ต้องทำคือการใช้ข้อต่อหลวม

การมีเพศสัมพันธ์แบบหลวมหมายความว่า A รู้จัก B แต่ B ไม่รู้ว่า A. ในคำอื่น ๆ ทั้งสองฝ่ายที่เกี่ยวข้องมีบทบาทลูกค้าและเซิร์ฟเวอร์ที่แตกต่างกันโดยที่ลูกค้ารู้จักเซิร์ฟเวอร์ แต่เซิร์ฟเวอร์ไม่รู้จักลูกค้า

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

หากต้องการวางไว้ในแง่ที่เป็นจริงมากขึ้นไม่มีที่ไหนในไฟล์ซอร์สโค้ดของลอจิกหากคุณพบคำสั่ง include / import / using ใด ๆ ที่อ้างถึงไฟล์ UI ในขณะที่ไฟล์ซอร์สโค้ดของ UI จะเต็มไปด้วย include / import / using คำสั่งที่อ้างถึงไฟล์ลอจิก

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

อนึ่งการออกแบบนี้ช่วยให้สิ่งอื่นที่คุณคาดหวังจากระบบดังกล่าว: มันเป็นไปได้ที่จะเสียบ UIs ที่แตกต่างกันมากเท่าที่คุณต้องการตรรกะและสิ่งทั้งหมดควรยังคงทำงาน


5

คุณควรแยกแต่ละชิ้นส่วนของ Model, View & Controller แต่ไม่มีเหตุผลว่าทำไมคุณไม่สามารถส่งวัตถุตัวอย่างระหว่างตัวควบคุมและมุมมองได้

ดังนั้นในกรณีของคุณHamburgerวัตถุจะเป็นส่วนหนึ่งของโมเดล จากนั้นคุณใช้คอนโทรลเลอร์ของคุณเพื่อดึงข้อมูลรายการที่ต้องการHamburgerและส่งวัตถุเหล่านั้นไปยังมุมมอง (คอมโบบ็อกซ์) เพื่อแสดง เมื่อผู้ใช้ของคุณเลือกแฮมเบอร์เกอร์แล้วคุณสามารถส่งHamburgerวัตถุกลับไปยังคอนโทรลเลอร์อีกครั้งเพื่อทำการประมวลผล

ประเด็นคือคุณยังคงสามารถทดสอบHamburgerตรรกะ"fetch s" และตรรกะ "กระบวนการHamburger" แยกต่างหากจากการแสดงผลที่แท้จริงของแฮมเบอร์เกอร์


ฉันเข้าใจ. อย่างไรก็ตามถ้าฉันปรับเปลี่ยนคลาส Hamburguer ฉันจะไม่ต้องแก้ไขรหัสของแบบฟอร์มที่เกี่ยวข้องกับวัตถุ Hamburguer ด้วยหรือไม่ การแยก UI-Logic อยู่ที่ไหน
Uri

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