ระดับความแตกต่างระหว่างคำตอบที่นี่แสดงให้เห็นว่าทำไมมันจึงเป็นแนวคิดที่ยากที่จะเข้าใจ แต่เพื่อให้ง่ายเหมือนที่ฉันสามารถอธิบายได้
เพื่อให้ฉันรู้ว่าถ้าฉันโยนลูกบอลให้คุณคุณสามารถจับมันได้ฉันไม่จำเป็นต้องรู้ว่าคุณอายุเท่าไหร่ ฉันไม่ต้องการที่จะรู้ว่าสิ่งที่คุณกินเป็นอาหารเช้าและฉันไม่สนใจว่าใครเป็นคนแรกที่คุณสนใจ สิ่งที่ฉันต้องรู้ก็คือคุณสามารถจับได้ ถ้าฉันรู้สิ่งนี้ฉันก็ไม่สนหรอกว่าคุณเป็นใครฉันจะส่งลูกบอลให้คุณหรือพี่ชายของคุณ
ด้วยภาษาที่ไม่ใช่ไดนามิกเช่น c # หรือ Java เป็นต้นเราสามารถทำสิ่งนี้ผ่านอินเทอร์เฟซ ดังนั้นสมมติว่าเรามีอินเทอร์เฟซต่อไปนี้:
public ICatcher
{
public void Catch();
}
และตอนนี้สมมติว่าเรามีคลาสดังต่อไปนี้:
public CatcherA : ICatcher
{
public void Catch()
{
console.writeline("You Caught it");
}
}
public CatcherB : ICatcher
{
public void Catch()
{
console.writeline("Your brother Caught it");
}
}
ขณะนี้ทั้ง CatcherA และ CatcherB ใช้วิธี Catch ดังนั้นบริการที่ต้องการ Catcher สามารถใช้อย่างใดอย่างหนึ่งเหล่านี้และไม่ให้แช่งที่จริง ดังนั้นการบริการที่เชื่อมโยงกันอย่างแน่นหนาอาจจะติดตั้งเช่นจับโดยตรง
public CatchService
{
private CatcherA catcher = new CatcherA();
public void CatchService()
{
catcher.Catch();
}
}
ดังนั้น CatchService อาจทำสิ่งที่กำหนดไว้ แต่จะใช้ CatcherA และจะเป็นผู้ใช้ CatcherA เสมอ มันยากในการเข้ารหัสดังนั้นมันอยู่ที่นั่นจนกว่าจะมีใครบางคนมาและ refactors มัน
ตอนนี้ให้ใช้ตัวเลือกอื่นที่เรียกว่าการฉีดพึ่งพา:
public CatchService
{
private ICatcher catcher;
public void CatchService(ICatcher catcher)
{
this.catcher = catcher;
catcher.Catch();
}
}
ดังนั้น calss ที่ติดตั้ง CatchService อาจทำสิ่งต่อไปนี้:
CatchService catchService = new CatchService(new CatcherA());
หรือ
CatchService catchService = new CatchService(new CatcherB());
ซึ่งหมายความว่าบริการ Catch ไม่ได้เชื่อมต่ออย่างแน่นหนากับ CatcherA หรือ CatcherB
มีอีกหลายกลยุทธ์สำหรับบริการคลัปเช่นการใช้เฟรมเวิร์ก IoC เป็นต้น