การฉีดพึ่งพา: ฉันควรใช้กรอบ?


24

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

เมื่อวัตถุต้องถูกสร้างในหลาย ๆ ที่เราก็มีฟังก์ชั่น (บางครั้งเป็นวิธีการเรียนของวัตถุนั้น) เพื่อสร้างอินสแตนซ์การผลิต ฟังก์ชั่นนี้ถูกเรียกเมื่อใดก็ตามที่เราต้องการวัตถุนั้น

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

ดังที่ฉันพูดโดยทั่วไปแล้วสิ่งนี้ใช้ได้ดี

ตอนนี้ฉันกำลังเข้าสู่โครงการ Java ใหม่และเรากำลังตัดสินใจว่าจะใช้เฟรมเวิร์ก DI หรือทำ DI ด้วยตนเอง (เช่นในโครงการก่อนหน้านี้)

โปรดอธิบายว่าการทำงานกับกรอบงาน DI จะแตกต่างกันอย่างไรและในลักษณะใดมันจะดีกว่าหรือแย่กว่าการฉีด 'vanilla' แบบพึ่งพา

แก้ไข: ฉันต้องการเพิ่มคำถาม: คุณเคยเห็นโครงการ 'ระดับมืออาชีพ' ที่ทำ DI ด้วยตนเองโดยไม่มีกรอบหรือไม่


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

4
ฉันเดาว่าคุณได้ตรวจสอบแล้วในกรณีที่คุณไม่ทำไมเราต้องกรอบสำหรับ DI?
Laiv

คำตอบ:


19

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

พื้นหลัง

ปีที่ผ่านมาสิ่งที่เป็นนามธรรมเช่นต้องให้เราเขียน config ไฟล์ต่างๆ ( การเขียนโปรแกรมที่เปิดเผย ) มันวิเศษมากที่เห็นจำนวน LOC ลดน้อยลงอย่างมาก แต่ในขณะที่ LOCS ลดลงจำนวนของไฟล์กำหนดค่าก็เพิ่มขึ้นเล็กน้อย สำหรับโครงการขนาดกลางหรือขนาดเล็กมันไม่ได้เป็นปัญหา แต่สำหรับโครงการขนาดใหญ่ที่มี "แอสเซมบลีของโค้ด" กระจายอยู่ 50% ระหว่างโค้ดและตัวอธิบาย XML กลายเป็นความเจ็บปวดใน ... อย่างไรก็ตามปัญหาหลักคือ กระบวนทัศน์ของตัวเอง มันค่อนข้างยืดหยุ่นเนื่องจากตัวอธิบายใช้พื้นที่น้อยในการปรับแต่ง

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

อาจเป็นความแตกต่างที่สำคัญที่สุดเกี่ยวกับวิธีการทำงานของคุณจนถึงขณะนี้ รหัสน้อยลงและความมหัศจรรย์มากขึ้น

ที่ด้านล่าง ...

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

นี่เป็นแต้มต่อสำหรับผู้ที่เรียน DI ด้วย DI container พวกเขาไม่เข้าใจความเกี่ยวข้องของรูปแบบการออกแบบการปฏิบัติที่ดีและหลักการที่ถูกยึดไว้โดยคอนเทนเนอร์ ฉันถามนักพัฒนาว่าพวกเขาคุ้นเคยกับ DI และข้อดีของมันหรือไม่และพวกเขาตอบว่า: - ใช่ฉันใช้ Spring IoC - (มันหมายถึงอะไรนรก!?)

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

ในด้านบวก ...

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

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

การทดสอบ

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

ฟังดูน่าดึงดูดใช่มั้ย ระวัง! อย่าตกหลุมพราง !!

ข้อเสนอแนะ

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

เกี่ยวกับการปฏิบัตินี้:

ควรใช้ DI คอนเทนเนอร์เมื่อใด

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

ฉันคิดว่าคุณจะพบที่น่าสนใจบทความมาร์ค Seeman ของเกี่ยวกับเรื่องนี้ซึ่งยังตอบคำถามเกี่ยวกับวิธีการใช้ DI

สุดท้ายหากเรากำลังพูดถึง Java ผมจะพิจารณาก่อนการมองไปที่JSR330 - พึ่งพาการฉีด

สรุป

ประโยชน์ :

  • ลดต้นทุนและประหยัดเวลา ผลผลิต
  • ส่วนประกอบจำนวนน้อย
  • รหัสจะง่ายขึ้นและสะอาดขึ้น

ข้อเสีย :

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

ความแตกต่างกับ DI บริสุทธิ์ :

  • รหัสน้อยลงและไฟล์การกำหนดค่าเพิ่มเติมหรือคำอธิบายประกอบ

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

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

ถ้านั่นคือสิ่งที่คุณหมายถึงพิจารณา: "กรอบเหล่านี้ไม่ได้ป้องกันคุณจากการทดสอบหน่วยหรือการทดสอบความสมบูรณ์ดังนั้นคุณไม่ต้องกังวลเกี่ยวกับวิธีที่พวกเขาส่งผลกระทบต่อการทดสอบ"
candied_orange

srry ฉันพยายามที่จะบอกว่าเขาจะสามารถทดสอบโค้ดของเขาได้แม้จะอยู่ในกรอบงานเหล่านี้ แม้จะมีสิ่งที่เป็นนามธรรม แต่การทดสอบก็ยังทำได้ รู้สึกอิสระที่จะแก้ไขคำตอบของฉัน ตามที่คุณเห็นว่าภาษาอังกฤษของฉันยังห่างไกลจากความเป็นจริง :-)
16:59

1
โปรดทราบว่า Dagger2 นั้น DI ต่างกันเล็กน้อย รหัสกาวถูกสร้างขึ้นในเวลาคอมไพล์ตามปกติแหล่ง Java ที่สามารถอ่านได้ดังนั้นจึงง่ายกว่ามากในการทำตามวิธีการที่สิ่งต่าง ๆ เข้าด้วยกันแทนที่จะต้องจัดการกับเวทมนตร์แบบรันไทม์
Thorbjørn Ravn Andersen

10

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

วัตถุที่ไม่ใช่โลก

ในบางกรณีคุณต้องการฉีดวัตถุร่วม: วัตถุที่จะมีเพียงหนึ่งอินสแตนซ์ในแอปพลิเคชันที่ทำงานอยู่ของคุณ นี่อาจเป็น a MarkdownToHtmlRendererer, a DatabaseConnectionPool, ที่อยู่สำหรับเซิร์ฟเวอร์ api ของคุณเป็นต้นสำหรับกรณีเหล่านี้เฟรมเวิร์กการฉีดของการพึ่งพาทำงานได้ง่ายมากคุณเพียงแค่เพิ่มการพึ่งพาที่จำเป็นให้กับคอนสตรัคเตอร์ของคุณและคุณได้รับแล้ว

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

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

ห้องสมุด

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

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

ความซับซ้อนที่ซ่อนอยู่

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

การสนับสนุน IDE

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

ข้อสรุป

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


นี่เป็นคำตอบที่ดีมาก แต่ฉันนึกภาพออกไม่ได้ว่าใช้คอนเทนเนอร์ IoC สำหรับห้องสมุดชั้นเรียน นั่นให้ความรู้สึกเหมือนการออกแบบที่ไม่ดีสำหรับฉัน ฉันคาดหวังว่าห้องสมุดจะให้ฉันระบุสิ่งที่มันต้องการอย่างชัดเจน
RubberDuck

@RubberDuck ในกรณีของฉันฉันทำงานให้กับ บริษัท ขนาดใหญ่ที่มีโปรเจ็กต์จาวาจำนวนมากที่ได้มาตรฐานทั้งหมดในกรอบการฉีดที่พึ่งพาเดียวกัน ณ จุดนั้นมันดึงดูดให้บางทีมส่งออกไลบรารี่ที่คาดว่าจะรวมตัวกันโดยกรอบการทำงาน DI แทนที่จะเป็นอินเทอร์เฟซภายนอกที่สมเหตุสมผล
Winston Ewert

@WinstonEwert เป็นโชคร้าย ขอบคุณสำหรับการกรอกในบริบทสำหรับฉัน
RubberDuck

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

IntelliJ เข้าใจ CDI (Java EE standard DI)
Thorbjørn Ravn Andersen

3

Java + การพึ่งพาการฉีด = เฟรมเวิร์กจำเป็นหรือไม่?

เลขที่

กรอบ DI ซื้ออะไรให้ฉัน

การสร้างวัตถุเกิดขึ้นในภาษาที่ไม่ใช่ Java


หากวิธีการจากโรงงานดีพอสำหรับความต้องการของคุณคุณสามารถทำ DI ใน java เฟรมเวิร์กฟรีใน pojo java แท้ 100% หากความต้องการของคุณไปไกลกว่านั้นคุณมีตัวเลือกอื่น ๆ

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

มีรูปแบบการสร้างสรรค์มากมายที่ออกมาหลังจาก Gang of Four ตัวสร้าง Josh Bloch เป็นแฮ็คที่ยอดเยี่ยมเกี่ยวกับการขาดพารามิเตอร์ที่มีชื่อของจาวา นอกเหนือจากนั้นคือผู้สร้าง iDSL ที่ให้ความยืดหยุ่นสูง แต่สิ่งเหล่านี้เป็นตัวแทนของงานสำคัญและสำเร็จรูป

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

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

หากการทดสอบเป็นแรงผลักดันที่อยู่เบื้องหลังสิ่งนี้โปรดดูที่: jUnit (ใด ๆ xUnit จริง ๆ )และMockito (เยาะเย้ยจริง ๆ )ก่อนที่คุณจะเริ่มคิดกรอบ DI ควรจะใช้ชีวิตของคุณ

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


PowerMock ได้แก้ไขกรณีเหล่านี้บางส่วนแล้ว อย่างน้อยก็ให้คุณจำลองสถิตยศาสตร์
Laiv

Meh หากคุณทำ DI อย่างถูกต้องมันค่อนข้างง่ายที่จะสลับหนึ่งเฟรมเวิร์ก IoC Container สำหรับเฟรมอื่น อย่าใช้คำอธิบายประกอบเหล่านั้นในรหัสของคุณและคุณจะไม่เป็นไร โดยทั่วไปให้ใช้คอนเทนเนอร์ IoC เพื่อทำ DI แทนการใช้คอนเทนเนอร์เป็นตัวระบุบริการ
RubberDuck

@RubberDuck ถูกต้อง ขาดการทดสอบและการบำรุงรักษารหัสฐานของคุณอย่างต่อเนื่องภายใต้กรอบ DI หลายอันคุณรู้วิธีที่เชื่อถือได้ง่าย ๆ ในการตรวจสอบว่า "คุณกำลังทำ DI ถูกต้องหรือไม่" แม้ว่าฉันจะไม่ใช้อะไรเลยนอกจาก pojo ในภาษาจาวาถ้าความพยายามอย่างมากในการสร้าง XML มันก็ยังไม่ง่ายนักเมื่อ XML นั้นขึ้นอยู่กับคอนเทนเนอร์ IoC
candied_orange

@CandiedOrange ฉันใช้ "ง่าย" เป็นคำที่เกี่ยวข้อง ในรูปแบบที่ยิ่งใหญ่ของสิ่งต่าง ๆ การแทนที่รูตองค์ประกอบหนึ่งด้วยอีกอันหนึ่งไม่ใช่งานยากเกินไป ไม่กี่วันทำงานท็อปส์ซู สำหรับการทำให้แน่ใจว่าคุณกำลังทำ DI อย่างถูกต้องนั่นคือสิ่งที่ Code Reviews มีไว้สำหรับ
RubberDuck

2
@RubberDuck ส่วนใหญ่ "root องค์ประกอบ" ที่ฉันเคยเห็นมีประมาณ 5 บรรทัดของรหัสในหลัก ไม่เลย ไม่ใช่งานที่ยากเกินไป มันเป็นสิ่งที่เป็นกรรมสิทธิ์ที่หนีเส้นเหล่านั้นที่ฉันเตือน คุณเรียกมันว่า "กำลังทำ DI อย่างถูกต้อง" ฉันถามคุณว่าคุณจะใช้อะไรในการพิสูจน์ปัญหาในการตรวจสอบโค้ด หรือคุณจะพูดว่า "Meh"
candied_orange

2

การสร้างชั้นเรียนและมอบหมายให้พวกเขาพึ่งพาเป็นส่วนหนึ่งของกระบวนการสร้างแบบจำลองส่วนสนุก นี่คือเหตุผลที่โปรแกรมเมอร์ส่วนใหญ่สนุกกับการเขียนโปรแกรม

การตัดสินใจการใช้งานที่จะใช้และวิธีการสร้างคลาสเป็นสิ่งที่จะต้องดำเนินการอย่างใดและเป็นส่วนหนึ่งของการกำหนดค่าแอปพลิเคชัน

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

การใช้ IDEs ที่ทันสมัยช่วยให้คุณสำรวจวิธีการและวิธีการใช้งาน การมีโรงงานเขียนด้วยตนเองนั้นค่อนข้างดีเพราะคุณสามารถเน้นคอนสตรัคเตอร์ของคลาสแสดงการใช้งานของมันและมันจะแสดงให้คุณเห็นสถานที่ทั้งหมดที่และวิธีการสร้างคลาสที่เฉพาะเจาะจง

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

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

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

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

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


ประสบการณ์ส่วนตัว (คำเตือน: ส่วนตัว)

การพูดในฐานะนักพัฒนา PHP แม้ว่าฉันจะชอบแนวคิดเบื้องหลังกรอบ DI แต่ฉันก็เคยใช้มันครั้งเดียว นั่นคือเมื่อทีมที่ฉันทำงานด้วยควรจะปรับใช้แอปพลิเคชันอย่างรวดเร็วและเราไม่ต้องเสียเวลาเขียนโรงงาน ดังนั้นเราก็หยิบขึ้นกรอบ DI, การกำหนดค่าและมันทำงานอย่างใด

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


2

ส่วนตัวฉันไม่ได้ใช้ DI-container และไม่ชอบพวกมัน ฉันมีเหตุผลอีกสองสามข้อสำหรับสิ่งนั้น

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

มันทำลายหลักการ OOPเช่นการรวมตัวกันและการเปรียบเทียบวัตถุเลโก้อิฐของเดวิดเวสต์

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


1

ดังที่คุณได้สังเกตเห็น: มีมุมมองที่แตกต่างกันออกไปทั้งนี้ขึ้นอยู่กับภาษาที่คุณใช้ diffenrent ใช้วิธีจัดการกับปัญหาที่คล้ายกัน

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

หากการออกแบบของคุณดีขึ้นคุณมักจะมีชั้นเรียนไม่กี่ชั้นที่มีการพึ่งพาหลายคนดังนั้นการเดินสายของการพึ่งพา - ไม่ว่าจะด้วยมือหรือโดยกรอบงาน - ควรจะค่อนข้างง่ายและปริมาณของการเขียนแบบทดสอบควรจะจัดการได้ง่าย

ที่กล่าวว่าไม่จำเป็นสำหรับ DI-framework

แต่ทำไมคุณถึงต้องการใช้เฟรมเวิร์ก

I)หลีกเลี่ยงรหัสสำเร็จรูป

หากโครงการของคุณมีขนาดที่คุณรู้สึกถึงความเจ็บปวดจากการเขียนโรงงาน (และ instatiations) ซ้ำแล้วซ้ำอีกคุณควรใช้ DI-framework

II)วิธีการปฏิเสธการเขียนโปรแกรม

เมื่อ Java ที่ครั้งหนึ่งเคยเขียนโปรแกรมกับ XMLก็คือตอนนี้: โรย Fairydust ด้วยคำอธิบายประกอบและความมหัศจรรย์ที่เกิดขึ้น

แต่อย่างจริงจัง: ผมเห็นชัดเจนคว่ำนี้ คุณสื่อสารเจตนาอย่างชัดเจนด้วยการพูดในสิ่งที่ต้องการแทนที่จะหาที่และวิธีการสร้าง


TL; DR

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


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

1
ฉันคิดว่ามันถูกต้องเสมอที่จะรู้ว่าสิ่งต่าง ๆ ทำงานอย่างไรภายใต้ประทุน แต่มันก็ไม่ควรทำให้คุณไม่รู้ ผมคิดว่าจุดขายสำหรับฤดูใบไม้ผลิเช่นคือว่ามันเป็นเพียงแค่การทำงาน และใช่คุณมีสิทธิ์อย่างยิ่งที่ในการตัดสินใจอย่างรอบคอบว่าจะใช้กรอบงานคุณต้องมีความรู้ในระดับหนึ่ง แต่ฉันเห็นบ่อยครั้งที่รูปแบบความคลางแคลงใจสำหรับผู้ที่ไม่ได้มีแผลเป็นเหมือนตัวเองแม้ว่าจะไม่ใช่ในกรณีของคุณที่มีความเชื่อมีเพียงคนที่มีประสบการณ์การล่าสัตว์ด้วยมือเท่านั้นที่ได้รับอนุญาตให้ไปที่ซุปเปอร์มาร์เก็ต
Thomas Junk

โชคดีที่ในวันนี้เราไม่ต้องการแม้แต่ Spring หรือ DI Frameworks สำหรับ Java เราได้รับJSR330ซึ่งเป็นเรื่องน่าเศร้า (อย่างน้อยฉันก็ไม่เห็นโครงการที่กำลังดำเนินการอยู่) ดังนั้นประชาชนยังคงได้เวลาของพวกเขาชนะรอยแผลเป็น :-)
LAIV

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

1
คำตอบเปลี่ยนไปน้อยมาก !!! ไม่มีอะไรที่น่าเป็นห่วง :-) ข้อความและข้อโต้แย้งยังคงเหมือนเดิม ฉันแค่อยากให้คำตอบของคุณเป็นแบบนี้ต่อไป ฉันเดาว่ามันจะพาคุณไปลบหนึ่งในคำพูด
Laiv

0

ใช่. คุณควรอ่านหนังสือของ Mark Seemann เรื่อง "การพึ่งพาการฉีด" เขาสรุปแนวทางปฏิบัติที่ดีบางอย่าง จากสิ่งที่คุณพูดคุณอาจได้ประโยชน์จาก คุณควรตั้งเป้าหมายว่าจะมีรากองค์ประกอบหนึ่งหรือรากองค์ประกอบหนึ่งต่อหน่วยงาน (เช่นคำขอเว็บ) ฉันชอบวิธีคิดของเขาว่าวัตถุใด ๆ ที่คุณสร้างถือเป็นการพึ่งพา (เช่นพารามิเตอร์ใด ๆ กับวิธีการ / คอนสตรัคเตอร์) ดังนั้นคุณควรระวังว่าคุณจะสร้างที่ไหนและอย่างไร กรอบงานจะช่วยให้คุณเข้าใจแนวคิดเหล่านี้ชัดเจน หากคุณอ่านหนังสือของมาร์คคุณจะพบมากกว่าคำตอบสำหรับคำถามของคุณ


0

ใช่เมื่อทำงานใน Java ฉันจะแนะนำ DI Framework มีเหตุผลบางประการสำหรับสิ่งนี้:

  • Java มีแพ็คเกจ DI ที่ดีมากหลายตัวที่เสนอการฉีดแบบพึ่งพาอัตโนมัติและมักจะมาพร้อมกับความสามารถเพิ่มเติมที่ยากต่อการเขียนด้วยตนเองมากกว่า DI ง่าย (เช่นขอบเขตการพึ่งพาที่อนุญาตให้เชื่อมต่ออัตโนมัติระหว่างขอบเขตโดยการสร้างรหัสเพื่อค้นหาขอบเขต ใช้ d เพื่อค้นหารุ่นที่ถูกต้องของการพึ่งพาสำหรับขอบเขตนั้น - ดังนั้นสำหรับวัตถุที่กำหนดขอบเขตของแอปพลิเคชันสามารถอ้างถึงคำขอที่ถูกกำหนดขอบเขต)

  • คำอธิบายประกอบ java มีประโยชน์อย่างมากและเป็นวิธีที่ดีในการกำหนดค่าการพึ่งพา

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

  • เฟรมเวิร์ก Java DI สามารถทำสิ่งที่มีประโยชน์เช่นสร้างพร็อกซีและมัณฑนากรอัตโนมัติซึ่งทำงานใน Java มากกว่าภาษาแบบไดนามิก


0

หากโครงการของคุณมีขนาดเล็กเพียงพอและคุณไม่มีประสบการณ์มากนักกับ DI-Framework ฉันไม่แนะนำให้ใช้เฟรมเวิร์กและทำด้วยตนเอง

เหตุผล: ฉันเคยทำงานในโครงการที่ใช้สองไลบรารีที่มีการพึ่งพาโดยตรงไปยังเฟรมเวิร์ก di ที่แตกต่างกัน พวกเขาทั้งสองมีรหัสเฟรมเวิร์กเฉพาะเช่น di-give-me-an-instance-of-XYZ เท่าที่ฉันรู้ว่าคุณสามารถมีการใช้งาน di-framework หนึ่งครั้งเท่านั้น

ด้วยรหัสเช่นนี้คุณสามารถทำอันตรายได้มากกว่าผลประโยชน์

หากคุณมีประสบการณ์มากขึ้นคุณอาจหลีกเลี่ยง di-framwork โดยอินเทอร์เฟซ (โรงงานหรือ servicelocator) ดังนั้นปัญหานี้จะไม่มีอยู่อีกต่อไปและเฟรมเวิร์ก di จะได้รับประโยชน์มากกว่าที่เป็นอันตราย

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