ให้เราพยายามทำความเข้าใจผ่านสองตัวอย่าง
ตัวอย่างที่ 1
ในวันก่อนหน้านี้แอพที่ใช้ในการสร้างพรอมต์คำสั่งเพื่อยอมรับอินพุตของผู้ใช้ทีละรายการ วันนี้เฟรมเวิร์กของ UI ทำให้องค์ประกอบ UI ต่าง ๆ ยกตัวอย่างเหตุการณ์ต่าง ๆ ขององค์ประกอบ UI เหล่านั้น (เช่นเมาส์โฮเวอร์คลิก ฯลฯ ) และผู้ใช้ / โปรแกรมหลักมีตะขอ (ตัวอย่างเช่นฟังเหตุการณ์ UI ใน Java) สำหรับฟังเหตุการณ์เหล่านั้น ดังนั้นองค์ประกอบ UI หลัก "การควบคุม" จึงถูกย้ายจากโปรแกรมผู้ใช้ไปยังเฟรมเวิร์ก UI ในวันก่อนหน้ามันอยู่ในโปรแกรมผู้ใช้
ตัวอย่างที่ 2
พิจารณาชั้นCustomerProcessor
ล่าง:
class CustomerProcessor
{
SqlCustRepo custRepo = new SqlCustRepo();
private void processCustomers()
{
Customers[] custs = custRepo.getAllCusts();
}
}
หากฉันต้องการprocessCustomer()
เป็นอิสระจากการนำไปปฏิบัติใด ๆgetAllCusts()
ไม่ใช่แค่ที่จัดทำโดยSqlCustRepo
ฉันจะต้องกำจัดสาย: SqlCustRepo custRepo = new SqlCustRepo()
และแทนที่ด้วยสิ่งทั่วไปมากขึ้นความสามารถในการยอมรับการใช้งานที่หลากหลายเช่นที่processCustomers()
จะทำงานให้ การดำเนินการใด ๆ ที่จัดไว้ให้ รหัสข้างต้น (อินสแตนซ์ระดับที่จำเป็นSqlCustRepo
โดยตรรกะโปรแกรมหลัก) เป็นวิธีแบบดั้งเดิมและจะไม่ประสบความสำเร็จในเป้าหมายของ decoupling นี้จากการดำเนินงานของprocessCustomers()
getAllCusts()
ในการผกผันของการควบคุมคอนเทนเนอร์ instantiates ชั้นการดำเนินงานที่จำเป็น (ตามที่ระบุโดยพูดการกำหนดค่า xml), ฉีดมันในตรรกะโปรแกรมหลักซึ่งได้รับการผูกตามตะขอที่ระบุ (พูดโดย@Autowired
คำอธิบายประกอบหรือ getBean()
วิธีการในกรอบฤดูใบไม้ผลิ)
ให้ดูว่าสิ่งนี้สามารถทำได้ พิจารณารหัสด้านล่าง
config.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="custRepo" class="JsonCustRepo" />
</beans>
CustRepo.java
interface ICustRepo
{ ... }
JsonCustRepo.java
class JsonCustRepo implements CustRepo
{ ... }
App.java
class App
{
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext("Config.xml");
ICustRepo custRepo = (JsonCustRepo) context.getBean("custRepo");
}
}
เรายังสามารถมี
class GraphCustRepo implements ICustRepo { ... }
และ
<bean id="custRepo" class="GraphCustRepo">
และเราไม่จำเป็นต้องเปลี่ยน App.java
เหนือคอนเทนเนอร์ (ซึ่งเป็นสปริงเฟรมเวิร์ก) มีความรับผิดชอบในการสแกนไฟล์ xml ยกตัวอย่างถั่วชนิดที่ระบุและฉีดลงในโปรแกรมผู้ใช้ โปรแกรมผู้ใช้ไม่มีการควบคุมว่าคลาสใดถูกสร้างขึ้น
PS: IoC เป็นแนวคิดทั่วไปและสามารถทำได้หลายวิธี ตัวอย่างข้างต้นประสบความสำเร็จโดยการฉีดพึ่งพา
อ้างอิง: บทความของมาร์ตินฟาวเลอร์