ฉันเข้าใจประโยชน์ของการฉีดแบบพึ่งพาตัวเอง ยกตัวอย่างเช่น Spring ฉันยังเข้าใจประโยชน์ของคุณสมบัติอื่น ๆ ของ Spring เช่น AOP ตัวช่วยประเภทต่างๆ ฯลฯ ฉันแค่สงสัยว่าการกำหนดค่า XML มีประโยชน์อย่างไรเช่น:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
เมื่อเทียบกับรหัสจาวาเก่าธรรมดาเช่น:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
ซึ่งง่ายกว่าการดีบั๊กตรวจสอบเวลาคอมไพล์และทุกคนที่รู้จัก java เท่านั้น ดังนั้นวัตถุประสงค์หลักของกรอบการฉีดพึ่งพาคืออะไร? (หรือโค้ดที่แสดงประโยชน์ของมัน)
UPDATE:
ในกรณีของ
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
กรอบงาน IoC จะเดาได้อย่างไรว่าการใช้งาน myService ใดที่ฉันต้องการฉีดหากมีมากกว่าหนึ่ง หากมีการใช้งานอินเทอร์เฟซที่กำหนดเพียงรายการเดียวและฉันปล่อยให้คอนเทนเนอร์ IoC ตัดสินใจใช้โดยอัตโนมัติมันจะเสียหลังจากการใช้งานครั้งที่สองปรากฏขึ้น และหากมีการใช้งานอินเทอร์เฟซเพียงอย่างเดียวที่เป็นไปได้โดยเจตนาคุณก็ไม่จำเป็นต้องฉีดเข้าไป
มันน่าสนใจมากที่ได้เห็นส่วนกำหนดค่าเล็ก ๆ สำหรับ IoC ซึ่งแสดงให้เห็นถึงประโยชน์ของมัน ฉันใช้ Spring มาระยะหนึ่งแล้วและไม่สามารถยกตัวอย่างเช่นนี้ได้ และฉันสามารถแสดงบรรทัดเดียวซึ่งแสดงให้เห็นถึงประโยชน์ของ hibernate, dwr และเฟรมเวิร์กอื่น ๆ ที่ฉันใช้
อัปเดต 2:
ฉันทราบว่าการกำหนดค่า IoC สามารถเปลี่ยนแปลงได้โดยไม่ต้องคอมไพล์ใหม่ มันเป็นความคิดที่ดีจริงๆหรือ? ฉันเข้าใจได้เมื่อมีคนต้องการเปลี่ยนข้อมูลรับรอง DB โดยไม่ต้องคอมไพล์ใหม่ - เขาอาจไม่ใช่ผู้พัฒนา ในทางปฏิบัติของคุณคนอื่นที่ไม่ใช่นักพัฒนาเปลี่ยนแปลงการกำหนดค่า IoC บ่อยเพียงใด ฉันคิดว่าสำหรับนักพัฒนาไม่มีความพยายามที่จะคอมไพล์คลาสนั้นซ้ำแทนที่จะเปลี่ยนการกำหนดค่า และสำหรับผู้ที่ไม่ใช่นักพัฒนาคุณอาจต้องการทำให้ชีวิตของเขาง่ายขึ้นและมีไฟล์กำหนดค่าที่ง่ายกว่านี้
อัปเดต 3:
การกำหนดค่าภายนอกของการทำแผนที่ระหว่างอินเทอร์เฟซและการใช้งานคอนกรีต
อะไรคือสิ่งที่ดีในการทำให้มันขยายออกไป? คุณไม่ได้ทำให้โค้ดทั้งหมดของคุณเป็นภายนอกในขณะที่คุณทำได้อย่างแน่นอน - เพียงแค่วางไว้ในไฟล์ ClassName.java.txt อ่านและคอมไพล์ด้วยตนเองทันที - ว้าวคุณหลีกเลี่ยงการคอมไพล์ซ้ำ ทำไมต้องคอมไพล์?!
คุณประหยัดเวลาในการเข้ารหัสเนื่องจากคุณระบุการแมปอย่างเปิดเผยไม่ใช่ในรหัสขั้นตอน
ฉันเข้าใจว่าบางครั้งวิธีการที่เปิดเผยจะช่วยประหยัดเวลา ตัวอย่างเช่นฉันประกาศเพียงครั้งเดียวการแมประหว่างคุณสมบัติ bean กับคอลัมน์ DB และไฮเบอร์เนตใช้การแมปนี้ในขณะโหลดบันทึกสร้าง SQL ตาม HSQL เป็นต้นนี่คือที่ที่วิธีการประกาศทำงาน ในกรณีของ Spring (ในตัวอย่างของฉัน) การประกาศมีจำนวนบรรทัดมากกว่าและมีการแสดงออกเช่นเดียวกับรหัสที่เกี่ยวข้อง หากมีตัวอย่างเมื่อการประกาศดังกล่าวสั้นกว่ารหัส - ฉันต้องการดู
หลักการ Inversion of Control ช่วยให้สามารถทดสอบหน่วยได้ง่ายเพราะคุณสามารถแทนที่การใช้งานจริงด้วยของปลอมได้ (เช่นการแทนที่ฐานข้อมูล SQL ด้วยในหน่วยความจำ)
ฉันเข้าใจการผกผันของผลประโยชน์การควบคุม (ฉันชอบเรียกรูปแบบการออกแบบที่กล่าวถึงในที่นี้ว่า Dependency Injection เนื่องจาก IoC มีลักษณะทั่วไปมากกว่า - มีการควบคุมหลายประเภทและเราเปลี่ยนกลับเพียงอย่างเดียว - การควบคุมการเริ่มต้น) ฉันถามว่าทำไมบางคนถึงต้องการสิ่งอื่นที่ไม่ใช่ภาษาโปรแกรมสำหรับมัน แน่นอนฉันสามารถแทนที่การใช้งานจริงด้วยของปลอมโดยใช้โค้ด และรหัสนี้จะแสดงสิ่งเดียวกันกับการกำหนดค่า - มันจะเริ่มต้นฟิลด์ด้วยค่าปลอม
mary = new FakeFemale();
ฉันเข้าใจประโยชน์ของ DI ฉันไม่เข้าใจว่าการกำหนดค่า XML ภายนอกเพิ่มประโยชน์อะไรบ้างเมื่อเทียบกับการกำหนดค่าโค้ดที่ทำเหมือนกัน ฉันไม่คิดว่าควรหลีกเลี่ยงการรวบรวม - ฉันรวบรวมทุกวันและฉันยังมีชีวิตอยู่ ฉันคิดว่าการกำหนดค่า DI เป็นตัวอย่างที่ไม่ดีของวิธีการที่เปิดเผย การประกาศจะมีประโยชน์หากมีการประกาศครั้งเดียวและใช้หลายครั้งในรูปแบบต่างๆเช่น hibernate cfg ที่การแม็ประหว่างคุณสมบัติ bean และคอลัมน์ DB ใช้สำหรับบันทึกโหลดสร้างคิวรีการค้นหา ฯลฯ การกำหนดค่า Spring DI สามารถแปลเป็น configuring code เหมือนในตอนต้นของคำถามนี้ได้หรือไม่? และใช้สำหรับการเริ่มต้นถั่วเท่านั้นไม่ใช่หรือ? ซึ่งหมายความว่าวิธีการที่เปิดเผยไม่ได้เพิ่มอะไรที่นี่ใช่หรือไม่?
เมื่อฉันประกาศการทำแผนที่ไฮเบอร์เนตฉันแค่ให้ข้อมูลบางอย่างในโหมดไฮเบอร์เนตและมันก็ใช้งานได้ - ฉันไม่ได้บอกว่าต้องทำอะไร ในกรณีของฤดูใบไม้ผลิคำประกาศของฉันบอกให้สปริงต้องทำอย่างแน่นอน - ทำไมต้องประกาศทำไมไม่ทำ
การอัปเดตล่าสุด:
พวกคำตอบมากมายกำลังบอกฉันเกี่ยวกับการฉีดพึ่งพาซึ่งฉันรู้ว่าดี คำถามเกี่ยวกับจุดประสงค์ของการกำหนดค่า DI แทนการเริ่มต้นโค้ด - ฉันมักจะคิดว่าการเริ่มต้นโค้ดนั้นสั้นและชัดเจนกว่า คำตอบเดียวที่ฉันได้รับสำหรับคำถามของฉันคือหลีกเลี่ยงการคอมไพล์ซ้ำเมื่อการกำหนดค่าเปลี่ยนไป ฉันเดาว่าฉันควรโพสต์คำถามอื่นเพราะมันเป็นความลับที่ยิ่งใหญ่สำหรับฉันทำไมจึงควรหลีกเลี่ยงการรวบรวมในกรณีนี้