Dependency Inversion Principle
High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).
Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
High-level modules ไม่ควรที่จะ import low-level modules มาใช้ตรงๆ หากต้องการจะใช้ ควรจะให้มันยู่ที่ Protocal แทน
❌ Bad
อย่างเช่นผมมี class MessagingApp
แล้วผมอยากเรียกใช้ EmailService
ไว้ใน class MessagingApp
ด้วย เราไม่ควรที่จะสร้าง Object ไว้ใน class ตรงๆ
// Low-level module (Concrete implementation)
class EmailService {
func sendEmail ( message : String , to : String ) {
print ( " Email sent to \( to ) : \( message ) " )
}
}
// High-level module (Depends on low-level module directly)
class MessagingApp {
private let emailService = EmailService ()
func sendMessage ( message : String , to : String ) {
emailService. sendEmail ( message : message, to : to )
}
}
let messagingApp = MessagingApp ()
messagingApp. sendMessage ( message : " Hello " , to : " [email protected] " )
// Output: Email sent to [email protected] : Hello
✅ Good
แต่เราควรใช้วิธีการ initialize แทน นอกจากจะทำให้ code ดูเป็นสัดเป็นส่วนแล้ว ยังง่ายต่อการ Test อีกด้วย เพราะจะมองออกทันที ว่าอะไรเป็นอะไร
// Abstraction (Protocol)
protocol MessageService {
func sendMessage ( message : String , to : String )
}
// Low-level module (Concrete implementation)
class EmailService : MessageService {
func sendMessage ( message : String , to : String ) {
print ( " Email sent to \( to ) : \( message ) " )
}
}
// High-level module (Depends on abstraction)
class MessagingApp {
private let messageService: MessageService
init ( messageService : MessageService ) {
self.messageService = messageService
}
func sendMessage ( message : String , to : String ) {
messageService. sendMessage ( message : message, to : to )
}
}
// Using Dependency Inversion Principle
let emailService = EmailService ()
let messagingApp = MessagingApp ( messageService : emailService )
messagingApp. sendMessage ( message : " Hello " , to : " [email protected] " )
// Output: Email sent to [email protected] : Hello