การฉีดพึ่งพา: ณ จุดใดฉันได้รับอนุญาตให้สร้างวัตถุใหม่


13

ฉันกำลังปรับโครงสร้างแอปพลิเคชันPHPอีกครั้งและฉันพยายามทำให้มีการพึ่งพาการฉีด (DI) มากที่สุดเท่าที่จะทำได้

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

ฉัน refactoring เพื่อให้ฉันสามารถฉีดการพึ่งพามากกว่าการสร้างวัตถุใหม่ภายในชั้นเรียน แต่ในบางจุดฉันจะต้องสร้างวัตถุบางอย่างนั่นคือใช้newคำหลักที่หวั่น

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

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

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



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

คลาสระดับบนสุดที่คุณพูดถึงเป็นส่วนหนึ่งของรูทองค์ประกอบ มันไกลจากความผิด
อัตราส่วนของ Facio

คำตอบ:


12

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

มันดูเหมือนจะเป็นทางออกที่ได้รับการยอมรับเพื่อเพิ่มการสร้างวัตถุทั้งหมดภายในรูทองค์ประกอบนี้ (หรืออ้างอิงจากคอนเทนเนอร์ IoC จากที่นี่)

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

ชั้นระดับบนสุดอาจจะยุ่งบิตที่เกลื่อนไปด้วยnewและset_property()แต่ผมต้องบอกว่าที่จริงผมชอบที่มีทั้งหมดรหัสนี้ในสถานที่หนึ่งมากกว่ากระจัดกระจายทั่วชั้นเรียนอื่น ๆ

อื่นที่มีประโยชน์หน้าถกฮิตประสิทธิภาพของวิธีการนี้ที่นี่


1
+1 เพราะฉันไม่เคยได้ยินเกี่ยวกับ 'Composition Root' มาก่อน
c_maker

2

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

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

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


-2

สองเซ็นต์ของฉันที่นี่:

ฉันกำลัง refactoring แอปพลิเคชัน php และฉันพยายามทำมีการฉีดพึ่งพามากที่สุด

คุณไม่ระบุว่าคุณกำลังใช้เฟรมเวิร์กการฉีดพึ่งพาหรือไม่ ฉันคิดว่าคุณควรจะแน่นอน ใช้สิ่งที่ช่วยให้คุณมีคุณสมบัติที่คุณต้องการ: /programming/9348376/guice-like-dependency-injection-frameworks-in-php

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

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

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

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

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

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

ในคำอื่น ๆ ฉันจะบอกว่าการใช้รูปแบบ Factory สำหรับคลาสหรือกลุ่มของคลาสนั้นขึ้นอยู่กับว่าคุณต้องการสร้างโมเดลคลาสเหล่านั้นอย่างไรไม่ว่าคุณจะใช้ DI (เว้นแต่ว่าการใช้ DI ของคุณจะต้องใช้โรงงานอย่างชัดเจน

คุณยังกำหนดค่ากรอบ IoC ของคุณให้ใช้ Factory เมื่อคุณใช้ lib บุคคลที่สามซึ่งต้องการการใช้ Factory ในกรณีนี้คุณไม่มีการควบคุมเกี่ยวกับสิ่งนี้และคุณต้องบอกคอนเทนเนอร์ IoC ของคุณ: "เฮ้เมื่อฉันขออินเทอร์เฟซเหล่านี้คุณต้องใช้โรงงานนี้เพื่อให้อินสแตนซ์ที่เหมาะสมแก่ฉัน"

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

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

ฉันหวังว่ามันจะช่วย


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

4
doing DI manually beats the whole purpose of using an Inversion of Control container- หากคุณหมายถึง"... ซึ่งเป็นการรวมศูนย์การพึ่งพาของคุณไว้ในไฟล์กำหนดค่า"คุณก็พูดถูกเพราะนั่นคือคอนเทนเนอร์ IoC ทั้งหมดที่ทำ เป้าหมายที่แท้จริงของ DI คือ decoupling และคุณสามารถทำได้โดยการจัดหาการพึ่งพาของคุณในวิธีการสร้าง คุณไม่จำเป็นต้องมีกรอบ DI เลยในการทำเช่นนั้น
Robert Harvey

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

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

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