Dependency injection (DI) เป็นแนวคิดในการออกแบบที่ลดความผูกพันระหว่างคลาสหรืออ็อบเจกต์ ซึ่งจะทำให้มีการผูกพันลดลงและมีการส่งผ่านอิสระระหว่างกันมากขึ้น
Without Dependency Injection
ในตัวอย่างนี้เรามี class UserServiceWithoutDI
และทำการสร้าง Instance ของ EmailService
ภายใน class เลย
class UserServiceWithoutDI {
func registerUser(email: String, password: String) {
// โค้ดสำหรับการลงทะเบียนผู้ใช้งาน...
// ส่งอีเมลถึงผู้ใช้งาน
let emailService = EmailService()
emailService.sendEmail(to: email, message: "ยินดีต้อนรับสู่แพลตฟอร์มของเรา!")
}
}
class EmailService {
func sendEmail(to email: String, message: String) {
// โค้ดสำหรับการส่งอีเมล...
print("ส่งอีเมลไปยัง \(email): \(message)")
}
}
// การใช้งาน
let userService = UserServiceWithoutDI()
userService.registerUser(email: "[email protected]", password: "password123")
จากตัวอย่างด้านบน แน่นอนว่ามันทำงานได้ปกติ แต่มันมีการผูกติดกันและไม่ถูกตามหลัก OOP สักเท่าไหร่ ทำให้ยากต่อทดสอบและการแก้ไขในภายหลังด้วย
With Dependency Injection
วิธีการที่ดี เราควรจะทำด้วยวิธีการ initialize
แล้วทำการส่ง emailService
เข้าไปใน init
อีกที
class UserServiceWithDI {
let emailService: EmailService
init(emailService: EmailService) {
self.emailService = emailService
}
func registerUser(email: String, password: String) {
// โค้ดสำหรับการลงทะเบียนผู้ใช้งาน...
// ส่งอีเมลถึงผู้ใช้งานโดยใช้ EmailService ที่ถูกซึ่งเข้ามา
emailService.sendEmail(to: email, message: "ยินดีต้อนรับสู่แพลตฟอร์มของเรา!")
}
}
// สร้าง EmailService อย่างเดียวกับที่มีอยู่ก่อน
// การใช้งาน
let emailService = EmailService()
let userService = UserServiceWithDI(emailService: emailService)
userService.registerUser(email: "[email protected]", password: "password123")
อาจจะดูเหมือนเขียนเพิ่มอีกบรรทัด แต่จะทำให้ code ของเราแยกกัน และอ่านง่ายมากยิ่งขึ้นและทำให้ง่ายต่อการทดสอบอีกด้วย