typescript - การฉีดพึ่งพา (dependency injection) ใน Angular มีประโยชน์อย่างไร เพราะดูเหมือนไม่ได้แก้ปัญหาอะไรเลย?
สิ่งนี้สามารถปรับปรุงโค้ดของฉันได้อย่างไร? มันสามารถลบการพึ่งพาได้อย่างไร? ฉันยังไม่เห็นประโยชน์ใด ๆ ของการใช้สิ่งนี้
@Component({
selector: 'talk-list',
templateUrl: 'talks.html',
providers: [TalksAppBackend]
})
class TalkList {
constructor(backend:TalksAppBackend) {
this.talks = backend.fetchTalks();
}
}
ถ้าฉันได้ใช้
TalksAppBackend t=new TalksAppBackend(); นั่นก็จะเหมือนกัน นอกจากความแตกต่างด้านไวยากรณ์แล้ว มันแตกต่างกันมากแค่ไหน?
อัปเดต :
นอกจากนี้ มันเรียก .fetchTalks(); นั่นไม่ใช่การจำลอง มันเป็นไปได้อย่างไร?
คำตอบ #1
ถ้าคุณไม่ใช้ Dependency Injection
ความแตกต่างหลักคือ ถ้าคุณไม่ใช้ DI (dependency injection) โค้ดของคุณจะต้องรู้วิธีสร้าง dependencies ทั้งหมดของตัวเอง คุณอาจมีคอมโพเนนต์จำนวนมากที่ใช้บริการจำนวนมาก บริการเหล่านั้นอาจพึ่งพาบริการอื่น ๆ เช่น TalksAppBackend อาจต้องการบริการ HttpClient และโค้ดของคุณจะต้องสร้าง dependencies สำหรับ dependencies ของมัน เหมือนกับ
TalksAppBackend t = new TalksAppBackend(new HttpClient())และทุกส่วนประกอบของคุณต้องทำเช่นนั้น สร้างอินสแตนซ์ใหม่ของ TalksAppBackend และอินสแตนซ์ของ HttpClient และถ้าในภายหลัง TalksAppBackend ต้องการบริการล็อกบางอย่าง คุณต้องอัปเดตทุกส่วนประกอบของคุณด้วยตนเองเพื่อสร้างอินสแตนซ์ของ deps ทั้งหมดสำหรับ TalksAppBackend โค้ดเช่นนี้ยากต่อการบำรุงรักษาและใช้หน่วยความจำมากกว่าที่ควรเพราะไม่ได้แชร์อินสแตนซ์
หากคุณใช้ Dependency Injection
คุณแค่ระบุโมดูลหรือคอมโพเนนต์ที่รับผิดชอบในการสร้างอินสแตนซ์ของดีเพนเดนซีที่ต้องการ มันจะดูแลดีเพนเดนซี่ของมันด้วย คอมโพเนนต์ของคุณเพียงแค่ระบุคลาสที่ต้องการ TalksAppBackend เพื่อให้ถูกฉีดเข้าไป และไม่ต้องกังวลว่ามันต้องการ HttpClient หรือ Logger หรืออะไรก็ตามหรือไม่ DI จะจัดการงานนั้นให้ และคุณยังสามารถควบคุมมันได้ดี: เซอร์วิสระดับโลกที่ให้โดยโมดูลจะถูกสร้างเพียงครั้งเดียว ดังนั้นคอมโพเนนต์ของคุณสามารถแชร์อินสแตนซ์เดียวกันได้ และถ้าคุณต้องการ คุณสามารถให้มันในระดับคอมโพเนนต์ได้ เพื่อให้สามารถสร้างหลายอินสแตนซ์ และคอมโพเนนต์ลูกจะเข้าถึงเพียงอินสแตนซ์เดียวที่จำเป็นได้
และแนวทางนี้ยังเปิดทางให้สามารถจำลองการขึ้นต่อกันและให้บริการ TalksAppBackend ไม่ใช่บริการจริงแต่เป็นแบบจำลองที่มีคำตอบปลอมที่ไม่ต้องใช้การสื่อสารผ่านเครือข่ายและการรันเบื้องหลังเพื่อทดสอบว่าคอมโพเนนต์ของคุณตีความผลลัพธ์ตามที่ควรหรือไม่ และคุณสามารถทำได้โดยไม่ต้องแก้ไขโค้ดของคอมโพเนนต์ ดังนั้นในแนวทางนี้คอมโพเนนต์จะมุ่งเน้นไปที่การทำสิ่งที่มันควรทำเท่านั้น
คำตอบ #2
มันมีประโยชน์มากมาย
- การเขียนโค้ดด้วยคำสำคัญใหม่เป็นเรื่องยากที่จะทดสอบในแอปพลิเคชันขนาดใหญ่
- สำคัญ: พิจารณาว่าคุณกำลังสร้างอินสแตนซ์ของคลาสด้วยคีย์เวิร์ด new และหลังจากผ่านไปไม่กี่วันคุณต้องการเปลี่ยน/เพิ่มพารามิเตอร์ในคอนสตรัคเตอร์ของคลาสที่พึ่งพา จากนั้นคุณจะต้องเปลี่ยนโค้ดของคุณทุกที่ที่คุณใช้อินสแตนซ์ของคลาสเดียวกัน ซึ่งจะเป็นเรื่องใหญ่ในโปรเจกต์ขนาดใหญ่
- ตัวอย่างของการพึ่งพาที่ถูกสร้างโดยคลาสที่ต้องการพึ่งพาเหล่านั้นจะอยู่เฉพาะภายในคลาสและไม่สามารถแบ่งปันข้อมูลและตรรกะได้