ประโยชน์ของการใช้การพึ่งพาการฉีดและภาชนะบรรจุ IoC คืออะไร?


62

ฉันกำลังวางแผนที่จะพูดคุยเกี่ยวกับการพึ่งพาการฉีดและภาชนะบรรจุ IoC และฉันกำลังมองหาข้อโต้แย้งที่ดีสำหรับการใช้งาน

ประโยชน์ที่สำคัญที่สุดของการใช้เทคนิคนี้และเครื่องมือเหล่านี้คืออะไร


1
ดูที่นี่และที่นี่สำหรับคำตอบของ StackOverflow และที่นี่สำหรับบทความฉบับสมบูรณ์เกี่ยวกับ IoC และถ้าคุณต้องการโต้แย้งเพื่อเปรียบเทียบให้มุ่งหน้าไปที่ SO
Jesse C. Slicer

14
ไม่ใช่ก้น ... แต่ถ้าคุณไม่รู้ว่าทำไมควรใช้ DI / IOC ทำไมคุณถึงพูดถึงมัน แพ้เดิมพันหรือไม่? ;-)
Steven A. Lowe

2
@ สตีเว่นเจ้านายของเขาอาจขอให้เขาทำ

1
@ สตีเฟ่นฉันใช้ DI อยู่ตลอดเวลา (บางคนอาจพูดบ่อยเกินไป :-D) ฉันแค่มองหาข้อโต้แย้งที่ดีเพื่อให้คนอื่น ๆ ใช้มัน
Andy Lowry

2
คนไม่ค่อยพูดถึงDI มากเกินไป หากคุณประวิงการตัดสินใจทุกครั้งคุณจะต้องสร้าง OO ที่เทียบเท่ากับสปาเก็ตตี้โค้ด การมีการออกแบบที่สอดคล้องกันนั้นจำเป็นต้องมีการตัดสินใจที่แท้จริงในบางประเด็น
Macneil

คำตอบ:


47

สิ่งที่สำคัญที่สุดสำหรับผมคือการทำให้มันง่ายที่จะปฏิบัติตามหลักการ Single รับผิดชอบ

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

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

DI / IoC เป็นหนึ่งในสองสามสิ่งในอาชีพการเขียนโปรแกรมของฉันที่เป็น "ตัวเปลี่ยนเกม" มีช่องว่างขนาดใหญ่ระหว่างโค้ดที่ฉันเขียนก่อน & หลังการเรียนรู้ DI / IoC ขอผมเน้นอีกหน่อย ขนาดใหญ่ปรับปรุงคุณภาพรหัส


3
ทำไมหลักการ Open-Closed จึงเป็นเรื่องใหญ่ ถ้าคุณรู้สึกว่าคุณจำเป็นต้องเปลี่ยน API / อินเตอร์เฟสทำไมคุณไม่ควร?
Arne Evertsson

@ArneEvertsson ฟัง Robert C. Martin พูดคุยเกี่ยวกับหลักการเปิด คุณจะรู้แจ้ง
Alternatex

@AmeEvertsson Open-Closed มีความสำคัญมากเมื่อมีการให้รหัสของคุณ (เช่นผลิตภัณฑ์เชิงพาณิชย์) เป็นโมดูลสำหรับผู้อื่นที่จะใช้เนื่องจากจะทำให้รหัสของคุณสามารถปรับใช้ได้มากขึ้นโดยไม่ต้องเปลี่ยนให้คุณเปลี่ยน
James Ellis-Jones

2
DI ไม่ได้ทำให้มันง่ายในการจัดการการอ้างอิงเนื่องจากมันมีความซับซ้อนมากขึ้นกว่าเพียงแค่การสร้างการพึ่งพาในระดับที่เป็นรูปธรรม แต่จะให้ความยืดหยุ่น แต่ถ้าคุณไม่ทำการทดสอบหน่วย 'เหมาะสม' ความยืดหยุ่นนั้นมักไม่จำเป็น ข้อดีทั้งสองอย่างที่อธิบายไว้ยังใช้กับตัวระบุตำแหน่งบริการซึ่งง่ายกว่า
James Ellis-Jones

1
ฉันลงคะแนนคำตอบนี้ปีที่ผ่านมา; ต่อไปนี้เป็นข้อสังเกต: 1) ในทางปฏิบัติการใช้ DI อย่างกว้างขวางมีแนวโน้มที่จะทำงานกับ SRP เนื่องจากโปรแกรมเมอร์เพียงเพิ่มวิธีการใน "คอนโทรลเลอร์", "บริการ", "บริการ", "DAOs" ฯลฯ แทนการสร้างคลาสใหม่สำหรับ ฟังก์ชั่นใหม่ มันเป็นสิ่งที่คุณเห็นว่าเกิดขึ้นในโครงการ Java และ C # .NET ซึ่งใช้เฟรมเวิร์ก DI หรือคอนเทนเนอร์ 2) หลักการเปิดแบบปิดเป็นเพียงภาพลวงตาของเบอร์ทรานด์เมเยอร์เกี่ยวกับประโยชน์ของการสืบทอดคลาส (การนำไปใช้) หากคุณค้นหาในหนังสือของเขาที่มีขนาด 1,400 หน้าคุณจะเห็นสิ่งที่ฉันหมายถึง - มันช่างโง่จริงๆ
Rogério

9

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


3

ข้อดีของการฉีดพึ่งพาคือ:

  1. รหัสของคุณสะอาดและสามารถอ่านได้มากขึ้น
  2. รหัสเป็นแบบคู่อย่างอิสระ
  3. สามารถนำมาใช้ใหม่ได้มากขึ้นเนื่องจากการใช้งานมีการกำหนดค่าในไฟล์ XML ซึ่งสามารถนำมาใช้ในบริบทที่แตกต่างกัน
  4. รหัสสามารถทดสอบได้อย่างง่ายดายด้วยการใช้งานจำลองที่แตกต่างกัน

1

ฉันคิดว่าผลประโยชน์ที่เกิดขึ้นจริงเป็นเรื่องทางการเมืองมากกว่าทางเทคนิค DI เป็นเพียงทางเลือกให้กับรูปแบบService Locatorไม่มีอะไรเพิ่มเติม โดยตัวมันเองมันไม่ได้ทำให้ง่ายขึ้นในการทำตามหลักการเช่น SRP หรือ OCP หรือเพื่อแยกชั้น ผู้ตอบแบบสอบถามอื่น ๆ ที่นี่กำลังสับสนแนวคิดและเทคนิคที่แตกต่างกัน IMO

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

ตอนนี้ฉันรู้ว่าหลายคนจะไม่เห็นด้วยกับความคิดเห็นนี้ ฉันยินดีที่จะพูดคุยตัวอย่างที่เป็นรูปธรรม


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

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

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

@ Jonathan คุณควรอ่านบทความที่แนะนำ DIแล้ว; ผู้เขียนสรุปโดยบอกว่า DI และ ServiceLocator เป็น "ประมาณคร่าว ๆ " กับ "เล็กน้อยขอบ" สำหรับหลัง การเชื่อมต่อที่มีความสำคัญระหว่างส่วนประกอบและส่วนประกอบอื่น ๆ ซึ่งอาจมีการใช้งานหลายอย่าง ServiceLocator เป็นบริการโครงสร้างพื้นฐานที่มีการใช้งานเพียงครั้งเดียวจึงไม่เป็นปัญหา หมายเหตุฉันเขียนว่า "การอ้างอิงอินสแตนซ์เมื่อใดก็ตามที่เกี่ยวข้อง "; แน่นอนถ้าคุณต้องการแยกการกำหนดค่าจากการใช้งานคุณจะไม่ทำ
Rogério

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

-1

เมื่อใช้ DI เพื่อแสดงวัตถุภายในเพื่อจุดประสงค์ในการทดสอบรูปแบบจะถูกใช้งานอย่างไม่เหมาะสม


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

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