จะหลีกเลี่ยงอินเทอร์เฟซที่บ้าคลั่งใน UI ด้วยการฉีดแบบพึ่งพาได้อย่างไร


8

ปัญหา
ฉันเพิ่งอ่านมากเกี่ยวกับ Singletons ไม่ดีและวิธีการฉีดพึ่งพา (ซึ่งฉันเข้าใจว่าเป็น "ใช้อินเตอร์เฟส") ดีกว่า เมื่อฉันใช้ส่วนนี้กับ callbacks / interfaces / DI และปฏิบัติตามหลักการแยกส่วนติดต่อฉันสิ้นสุดค่อนข้างยุ่งเหยิง

การพึ่งพาของพาเรนต์ UI ที่โดยทั่วไปแล้วพวกเด็ก ๆ ทั้งหมดรวมกันดังนั้นยิ่งลำดับชั้นขององค์ประกอบ UI มากขึ้นเท่าใดคอนสตรัคเตอร์ก็ยิ่งบวมมากขึ้นเท่านั้น

ทางด้านบนของลำดับชั้น UI นั้นเป็นคลาสแอปพลิเคชันเก็บข้อมูลเกี่ยวกับการเลือกปัจจุบันและการอ้างอิงถึงโมเดล 3 มิติที่ต้องการสะท้อนการเปลี่ยนแปลง แอปพลิเคชั่นคลาสใช้งานอินเทอร์เฟซ 8 ตัวและนี่เป็นเพียงหนึ่งในห้าของผลิตภัณฑ์ (/ อินเตอร์เฟส) ที่จะเกิดขึ้น!

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

คำถาม
โครงการนี้น่าจะเหมาะสำหรับโครงการนี้หรือไม่
ถ้าไม่มีข้อบกพร่องพื้นฐานในการคิดและ / หรือการนำ DI มาใช้ซึ่งทำให้ยุ่งยาก

ข้อมูลเพิ่มเติมเกี่ยวกับโครงการ
ประเภท: ตะกร้าช้อปปิ้งสำหรับอพาร์ทเมนท์พร้อมระฆังและนกหวีด
ขนาด: 2 เดือนสำหรับการ
บำรุงรักษารหัสและ UI : ไม่มีการอัปเดตที่ใช้งานอยู่ แต่อาจ "รุ่น 2.0" ในภายหลัง
สภาพแวดล้อม: การใช้ C # ใน Unity ซึ่งใช้หน่วยงาน ระบบส่วนประกอบ

ในเกือบทุกกรณีการโต้ตอบกับผู้ใช้จะกระตุ้นการทำงานหลายอย่าง ตัวอย่างเช่นเมื่อผู้ใช้เลือกรายการ

  • ส่วน UI ที่แสดงรายการนั้นและคำอธิบายจำเป็นต้องได้รับการอัปเดต สำหรับสิ่งนี้มันยังต้องได้รับข้อมูลบางอย่างจากแบบจำลอง 3 มิติเพื่อคำนวณราคา
  • ยิ่งไปกว่า UI, ราคาทั้งหมดโดยรวมจะต้องมีการปรับปรุง
  • จำเป็นต้องมีฟังก์ชั่นที่เกี่ยวข้องในคลาสบนโมเดล 3 มิติเพื่อแสดงการเปลี่ยนแปลงที่นั่น

DI ไม่เพียง แต่เกี่ยวกับการใช้งานอินเตอร์เฟซมันเป็นความสามารถในการแลกเปลี่ยน concretions ซึ่งเป็นประโยชน์อย่างยิ่งในการทดสอบหน่วยทรงกลม ...
Robbie Dee

1
นอกจากนี้ฉันยังไม่เห็นปัญหาที่ซิงเกิลตันเป็นทางออกที่ต้องการ ตัวอย่างแบบบัญญัติซึ่งผู้คนมักจะกล่าวถึงเสมอเป็นตัวเขียนบันทึก แต่แม้ที่นี่คุณอาจต้องการเขียนไปยังบันทึกที่แตกต่างกันจำนวนมาก (ข้อผิดพลาดการดีบัก ฯลฯ )
Robbie Dee

@ RobbieDee ใช่ DI เป็นเรื่องเกี่ยวกับมากกว่า แต่ฉันไม่สามารถดูสถานการณ์ที่ใช้อินเทอร์เฟซไม่ DI และถ้าซิงเกิลตันไม่ใช่คำตอบที่ต้องการ - ซึ่งฉันก็ถือว่า - แล้วทำไมคำตอบที่ดีที่สุดคือยุ่ง? นั่นคือคำถามหลักของฉัน แต่ฉันต้องการที่จะให้มันเปิดเพราะบางครั้งกฎทั่วไปใช้ไม่ได้
R. Schmitz

การจัดอินเตอร์เฟซการประสานงานยังเป็นคุณสมบัติของกรอบการเยาะเย้ย พวกเขาได้รับยังอยู่ในภาษา OO ไม่กี่ทศวรรษที่ผ่านมาดี ...
ร็อบบี้ดี

ฉันไม่เข้าใจคุณ
R. Schmitz

คำตอบ:


4

ฉันคิดว่าคำถามเป็นอาการไม่ใช่วิธีแก้ปัญหา

ฉันเพิ่งอ่านมากเกี่ยวกับ Singletons ที่ไม่ดีและวิธีการฉีดพึ่งพา (ซึ่งฉันเข้าใจว่าเป็น "ใช้อินเตอร์เฟซ") ดีกว่า เมื่อฉันใช้ส่วนนี้กับ callbacks / interfaces / DI และปฏิบัติตามหลักการแยกส่วนติดต่อฉันสิ้นสุดค่อนข้างยุ่งเหยิง

วิธีการแก้ปัญหาที่กำลังมองหาปัญหา; สิ่งนั้นและการเข้าใจผิดมันอาจเป็นการทำลายการออกแบบ คุณได้อ่านคำถามเกี่ยวกับDI vs Singleton แนวคิดที่แตกต่างหรือไม่? ฉันอ่านว่าเป็นเพียงการตัดซิงเกิลตันเพื่อให้ลูกค้าไม่ต้องจัดการกับซิงเกิล It.is.just.good.old.encapsulation ฉันคิดว่าเป็นจุดที่


ยิ่งลำดับชั้นขององค์ประกอบ UI มากขึ้นเท่าใดตัวสร้างก็จะยิ่งใหญ่

สร้างบิตขนาดเล็กก่อนจากนั้นส่งพวกเขาไปยังตัวสร้างของสิ่งที่พวกเขาอยู่และผ่านสิ่งที่ใหญ่กว่าเข้าไปในตัวสร้างของสิ่งที่ใหญ่กว่าต่อไป ...

หากคุณมีปัญหาการก่อสร้างที่ซับซ้อนให้ใช้รูปแบบโรงงานหรือผู้สร้าง บรรทัดล่างคือมีการก่อสร้างที่ซับซ้อนดึงเข้าไปในชั้นเรียนของตัวเองเพื่อให้ชั้นเรียนอื่น ๆ เรียบร้อยสะอาดเข้าใจ ฯลฯ


แอปพลิเคชั่นคลาสใช้งานอินเทอร์เฟซ 8 ตัวและนี่เป็นเพียงหนึ่งในห้าของผลิตภัณฑ์ (/ อินเตอร์เฟส) ที่จะเกิดขึ้น!

ฟังดูเหมือนไม่มีการขยายความสามารถ การออกแบบหลักหายไปและทุกอย่างถูกยัดเยียดจากด้านบน ควรมีการสร้างส่วนประกอบและการสืบทอดให้ได้มากขึ้น

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

ทบทวนการออกแบบของคุณตั้งแต่ต้นและตรวจสอบให้แน่ใจว่ามีผลิตภัณฑ์นามธรรมพื้นฐานที่สามารถสร้างขึ้นเพื่อให้การผลิตหมวดหมู่ที่ซับซ้อนหรือแตกต่างกันมากขึ้น ถ้าอย่างนั้นคุณควรมีคอลเล็กชันที่กำหนดเองของสิ่งต่าง ๆ เหล่านี้เพื่อให้คุณมีฟังก์ชั่น "ระดับคอลเลกชัน" เช่นที่ "โมเดล 3" ที่คุณพูดถึง


... โมเดล 3 มิติที่ต้องการสะท้อนการเปลี่ยนแปลง

สิ่งเหล่านี้ส่วนใหญ่อาจเหมาะกับคลาสการรวบรวมแบบกำหนดเอง มันอาจเป็นโครงสร้างระดับอิสระต่อตนเองเนื่องจากความลึกและความซับซ้อน สองสิ่งนี้ไม่ได้เกิดขึ้นพร้อมกัน

อ่านเกี่ยวกับรูปแบบของผู้เยี่ยมชม มันเป็นความคิดของการมีฟังก์ชั่นเต็มรูปแบบที่เชื่อมต่อกับประเภทต่างๆ


การออกแบบและ DI

90% ของการฉีดพึ่งพาทั้งหมดที่คุณจะทำคือการส่งผ่านพารามิเตอร์คอนสตรัค ดังนั้นคนที่เขียนหนังสือเล่มนี้ ออกแบบชั้นเรียนของคุณให้ดีและหลีกเลี่ยงการสร้างมลภาวะที่กระบวนการคิดด้วยความคิดที่คลุมเครือเกี่ยวกับความต้องการใช้ DI container-thingy ถ้าคุณต้องการมันการออกแบบของคุณจะแนะนำให้คุณพูด


มุ่งเน้นไปที่การสร้างแบบจำลองโดเมนช้อปปิ้งอพาร์ทเม้น

หลีกเลี่ยงวิธีการออกแบบของเจสสิก้าซิมป์สัน : "ฉันไม่รู้ว่ามันหมายถึงอะไร แต่ฉันต้องการมัน"

ต่อไปนี้เป็นเพียงความผิด:

  • ฉันควรจะใช้ส่วนต่อประสาน
  • ฉันไม่ควรใช้ซิงเกิล
  • ฉันต้องการ DI (อะไรก็ตามที่เป็น)
  • ฉันควรจะใช้องค์ประกอบไม่ใช่มรดก
  • ฉันควรหลีกเลี่ยงการสืบทอด
  • ฉันต้องใช้รูปแบบ

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

เพียงแค่จุดหนึ่งและฉันไม่ได้พยายามที่จะเป็นแวมไพร์ช่วยเหลือที่นี่ แต่มันเป็นชนิดของการเป็นส่วนหนึ่งของคำถามเดิม: มติทั่วไป (และมันขึ้นอยู่กับเหตุผลที่ถูกต้อง) ดูเหมือนว่าจะเป็นไปได้ว่าคุณเป็นจริงไม่ควรจะ ใช้ซิงเกิล คุณเขียน "'ฉันไม่ควรใช้ซิงเกิลตัน' ผิด" - ในกรณีใดจึงจะเหมาะสมที่จะใช้
R. Schmitz

ทั้งหมดที่ฉันพูดคือ "ขึ้นอยู่กับ" บ่อยครั้งที่ฉันเห็นว่ามีขนาดใหญ่มากอย่างแท้จริง
Radarbob

3

"การสืบทอดคลาส" เป็นธงสีแดงเล็กน้อย สมมุติฐาน: หน้าเว็บที่มี 5 วิดเจ็ต หน้านี้ไม่ใช่บรรพบุรุษของวิดเจ็ตใด ๆ อาจมีการอ้างอิงถึงวิดเจ็ตเหล่านั้น แต่มันไม่ได้เป็นบรรพบุรุษ แทนที่จะใช้การจัดลำดับชั้นเรียนพิจารณาใช้การจัดองค์ประกอบภาพ วิดเจ็ต 5 รายการแต่ละรายการสามารถสร้างได้ด้วยตนเองโดยไม่อ้างอิงกับวิดเจ็ตอื่นหรือหน้าบนสุด จากนั้นหน้าบนสุดจะถูกสร้างขึ้นพร้อมข้อมูลเพียงพอที่จะสร้างหน้าพื้นฐานและจัดวางวัตถุวิดเจ็ต (คอลเลกชัน) ที่ส่งไปให้ หน้านี้เป็นผู้รับผิดชอบการจัดวางและอื่น ๆ แต่ไม่ใช่การสร้างและตรรกะของวิดเจ็ต

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

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


ขออภัย "ลำดับชั้นของชั้นเรียน" เป็นข้อความที่ผิดที่นี่; อันที่จริงมันไม่ได้เป็นลำดับชั้นของคลาส แต่เป็นลำดับชั้นของ UI 'วิดเจ็ต' ไม่ใช่คลาสย่อยของคลาสแอปพลิเคชัน แต่ 'หน้า' เก็บการอ้างอิงไว้เพื่อเผยแพร่การอัปเดต UI มันสามารถทดสอบได้กับโครงสร้างนี้ แต่ก็มีค่าใช้จ่ายมากมายโดยเฉพาะในตัวสร้างเพียงแค่ส่งผู้ฟังจำนวนมากสำหรับเด็ก ๆ (UI)
R. Schmitz

@ R.Schmitz: ปัญหาค่าใช้จ่ายหรือไม่ UI ช้าหรือไม่และการออกแบบที่คุณอธิบายว่าเป็นความผิดหรือไม่
Robert Harvey

@ R.Schmitz คุณช่วยอธิบายเกี่ยวกับ "การส่งผ่านผู้ฟังจำนวนมาก" ได้ไหม? บางทีประสบการณ์ของฉันกับ DI ใน C # อาจต่ำ แต่มีบางอย่างบอกฉันว่าไม่จำเป็น (อย่างน้อยใน Constructor) ที่มีการออกแบบที่เหมาะสม
Katana314

@RobertHarvey ไม่มีการสูญเสียประสิทธิภาพเลยเพียงเกี่ยวกับความสามารถในการอ่าน
R. Schmitz

@ Katana314 ตัวอย่างเช่นเมื่อเพิ่มรายการ 3dmodel ต้องได้รับการอัปเดตและไม่ได้อยู่ในหมวดหมู่ผลิตภัณฑ์ใด ๆ ดังนั้นจึงอ้างอิงในคลาสแอปพลิเคชันซึ่งรับฟังรายการที่ถูกเพิ่ม / ลบ / เปลี่ยนแปลง ในท้ายที่สุดแล้วมันก็จะเหมือนกันสำหรับทุกประเภทผลิตภัณฑ์ ส่วน UI อื่น ๆ ก็ทำปฏิกิริยา (และฟัง) แต่ข้อความนั้นต้องเดินทางไปด้านบนเพราะนั่นคือจุดที่การอ้างอิง 3dmodel และข้อมูลจริง (ซึ่งก็มีการอัพเดทด้วย)
R. Schmitz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.