Inversion of Control เป็นหลักการออกแบบทั่วไปของสถาปัตยกรรมซอฟต์แวร์ที่ช่วยในการสร้างเฟรมเวิร์กซอฟต์แวร์แบบแยกส่วนที่สามารถนำมาใช้ซ้ำได้ซึ่งง่ายต่อการบำรุงรักษา
มันเป็นหลักการออกแบบที่การไหลของการควบคุมเป็น "ได้รับ" จากห้องสมุดที่เขียนทั่วไปหรือรหัสที่นำมาใช้ใหม่
เพื่อให้เข้าใจได้ดีขึ้นให้ดูว่าเราใช้รหัสอย่างไรในการเข้ารหัสก่อนหน้านี้ ในขั้นตอน / ภาษาดั้งเดิมตรรกะทางธุรกิจโดยทั่วไปจะควบคุมการไหลของแอปพลิเคชันและ "โทร" รหัสหรือฟังก์ชั่นทั่วไปหรือนำกลับมาใช้ซ้ำได้ ตัวอย่างเช่นในแอปพลิเคชันคอนโซลแบบง่ายโฟลว์การควบคุมของฉันถูกควบคุมโดยคำแนะนำของโปรแกรมของฉันซึ่งอาจรวมถึงการเรียกไปยังฟังก์ชั่นที่ใช้ซ้ำได้ทั่วไป
print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);
//More print and scan statements
<Do Something Interesting>
//Call a Library function to find the age (common code)
print Age
ในทางตรงกันข้ามกับ IoC Frameworks เป็นรหัสที่สามารถใช้ซ้ำได้ซึ่งเรียกว่า "ตรรกะทางธุรกิจ"
ตัวอย่างเช่นในระบบที่ใช้ windows กรอบจะพร้อมใช้งานเพื่อสร้างองค์ประกอบ UI เช่นปุ่มเมนูหน้าต่างและกล่องโต้ตอบ เมื่อฉันเขียนตรรกะทางธุรกิจของแอปพลิเคชันของฉันมันจะเป็นเหตุการณ์ของเฟรมเวิร์กที่จะเรียกรหัสตรรกะทางธุรกิจของฉัน (เมื่อมีเหตุการณ์ถูกไล่ออก) และไม่ใช่สิ่งที่ตรงกันข้าม
แม้ว่ารหัสของเฟรมเวิร์กจะไม่ทราบถึงตรรกะทางธุรกิจของฉัน แต่ก็ยังคงรู้วิธีเรียกรหัสของฉัน นี่คือความสำเร็จโดยใช้เหตุการณ์ / ผู้ได้รับมอบหมายการเรียกกลับ ฯลฯ นี่คือการควบคุมการไหลของ "Inverted"
ดังนั้นแทนที่จะขึ้นอยู่กับการไหลของการควบคุมบนวัตถุที่ถูกผูกไว้แบบคงที่การไหลขึ้นอยู่กับกราฟวัตถุโดยรวมและความสัมพันธ์ระหว่างวัตถุต่าง ๆ
Dependency Injection เป็นรูปแบบการออกแบบที่ใช้หลักการ IoC สำหรับการแก้ไขการพึ่งพาของวัตถุ
ในคำที่ง่ายกว่าเมื่อคุณพยายามเขียนโค้ดคุณจะสร้างและใช้คลาสที่แตกต่างกัน หนึ่งคลาส (Class A) อาจใช้คลาสอื่น (Class B และ / หรือ D) ดังนั้นคลาส B และ D จึงขึ้นกับคลาส A
การเปรียบเทียบง่ายๆจะเป็นรถคลาส รถอาจขึ้นอยู่กับชั้นเรียนอื่น ๆ เช่นเครื่องยนต์ยางรถยนต์และอื่น ๆ
การฉีดพึ่งพาแสดงให้เห็นว่าแทนที่จะเป็นคลาส Dependent (Class Car ที่นี่) เพื่อสร้างการพึ่งพา (Class Engine และคลาสยาง) คลาสควรถูกฉีดด้วยอินสแตนซ์ที่เป็นรูปธรรมของการพึ่งพา
ให้เข้าใจด้วยตัวอย่างที่เป็นประโยชน์มากขึ้น พิจารณาว่าคุณกำลังเขียน TextEditor ของคุณเอง เหนือสิ่งอื่นใดคุณสามารถมีเครื่องตรวจการสะกดคำที่ให้ความสะดวกแก่ผู้ใช้ในการตรวจสอบความผิดพลาดในข้อความของเขา การติดตั้งโค้ดอย่างง่ายสามารถ:
Class TextEditor
{
//Lot of rocket science to create the Editor goes here
EnglishSpellChecker objSpellCheck;
String text;
public void TextEditor()
{
objSpellCheck = new EnglishSpellChecker();
}
public ArrayList <typos> CheckSpellings()
{
//return Typos;
}
}
ตั้งแต่แรกเห็นทุกคนดูเป็นสีดอกกุหลาบ ผู้ใช้จะเขียนข้อความ ผู้พัฒนาจะจับข้อความและเรียกใช้ฟังก์ชัน CheckSpellings และจะพบรายการ Typos ที่เขาจะแสดงต่อผู้ใช้
ดูเหมือนว่าทุกอย่างจะทำงานได้ดีจนกระทั่งวันหนึ่งเมื่อผู้ใช้คนหนึ่งเริ่มเขียนภาษาฝรั่งเศสในเครื่องมือแก้ไข
เพื่อให้การสนับสนุนสำหรับภาษาอื่น ๆ เราจำเป็นต้องมี SpellCheckers มากขึ้น อาจเป็นภาษาฝรั่งเศสเยอรมันสเปนและอื่น ๆ
ที่นี่เราได้สร้างรหัสที่คู่กันอย่างแน่นหนาด้วย "SpellChecker" ภาษาอังกฤษ "ที่ถูกผนวกเข้ากับคลาส TextEditor ของเราอย่างแน่นหนาซึ่งหมายความว่าคลาส TextEditor ของเรานั้นขึ้นอยู่กับ EnglishSpellChecker หรือกล่าวอีกนัยหนึ่ง EnglishSpellCheker เราจำเป็นต้องลบการอ้างอิงนี้ เพิ่มเติมเครื่องมือแก้ไขข้อความของเราต้องการวิธีการอ้างอิงที่เป็นรูปธรรมของ Spell Checker ใด ๆ ตามดุลยพินิจของนักพัฒนาในขณะใช้งาน
ดังนั้นอย่างที่เราเห็นในการแนะนำ DI มันแสดงให้เห็นว่าชั้นควรถูกฉีดด้วยการพึ่งพา ดังนั้นจึงเป็นความรับผิดชอบของรหัสโทรศัพท์ในการฉีดการอ้างอิงทั้งหมดไปยังคลาส / รหัสที่เรียกว่า ดังนั้นเราสามารถปรับโครงสร้างรหัสของเราเป็น
interface ISpellChecker
{
Arraylist<typos> CheckSpelling(string Text);
}
Class EnglishSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
Class FrenchSpellChecker : ISpellChecker
{
public override Arraylist<typos> CheckSpelling(string Text)
{
//All Magic goes here.
}
}
ในตัวอย่างของเราคลาส TextEditor ควรรับอินสแตนซ์ที่เป็นรูปธรรมของชนิด ISpellChecker
ตอนนี้การพึ่งพาสามารถฉีดในตัวสร้างทรัพย์สินสาธารณะหรือวิธีการ
ให้ลองเปลี่ยนคลาสของเราโดยใช้ Constructor DI คลาส TextEditor ที่เปลี่ยนแปลงจะมีลักษณะดังนี้:
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
เพื่อให้รหัสโทรในขณะที่สร้างตัวแก้ไขข้อความสามารถฉีด SpellChecker Type ที่เหมาะสมกับอินสแตนซ์ของ TextEditor
คุณสามารถอ่านบทความฉบับสมบูรณ์ได้ที่นี่