Go'da Constructor Injection: Bağımlılıkları Doğru Geçmek

Constructor injection, bir struct'ın ihtiyaç duyduğu bağımlılıkları (başka nesneler, servisler, veritabanı bağlantıları) oluşturulurken dışarıdan geçmek demek. Go'da bu, fonksiyonlar aracılığıyla yapılır ve kodun test edilebilirliğini çok arttırır.
Eğer bir struct kendi bağımlılıklarını içinde oluşturursa, o bağımlılığı test sırasında sahte bir versiyon ile değiştiremezsin. Constructor injection kullanınca, test için mock nesneler kolayca geçebilirsin.

Praktik örneğe bakalım. Bir e-ticaret uygulamasında sipariş işleyen bir struct'ımız var. Bu struct'ın bir veritabanı ve bir e-posta servisi gerekli.

1package main
2
3import "fmt"
4
5type Database struct {
6connectionString string
7}
8
9func (d *Database) SaveOrder(orderId string) error {
10fmt.Printf("Sipariş %s veritabanına kaydedildi\n", orderId)
11return nil
12}
13
14type EmailService struct {
15smtpServer string
16}
17
18func (e *EmailService) SendConfirmation(email string) error {
19fmt.Printf("%s adresine onay e-postası gönderildi\n", email)
20return nil
21}
22
23type OrderProcessor struct {
24db *Database
25email *EmailService
26}
27
28func NewOrderProcessor(db *Database, email *EmailService) *OrderProcessor {
29return &OrderProcessor{
30db: db,
31email: email,
32}
33}
34
35func (op *OrderProcessor) ProcessOrder(orderId string, customerEmail string) error {
36op.db.SaveOrder(orderId)
37op.email.SendConfirmation(customerEmail)
38fmt.Printf("Sipariş %s işlendi\n", orderId)
39return nil
40}
41
42func main() {
43db:= &Database{connectionString: "postgres://..."}
44email:= &EmailService{smtpServer: "smtp.example.com"}
45
46processor:= NewOrderProcessor(db, email)
47processor.ProcessOrder("ORD-001", "user@example.com")
48}

Çıktı:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1Sipariş ORD-001 veritabanına kaydedildi
2user@example.com adresine onay e-postası gönderildi
3Sipariş ORD-001 işlendi

Gördüğün gibi NewOrderProcessor fonksiyonu (constructor) parametreleri alıyor ve struct'ı döndürüyor. Test yazarken Database ve EmailService yerine mock versiyonlarını geçebilirsin.

Test örneği:

1type MockDatabase struct {}
2
3func (m *MockDatabase) SaveOrder(orderId string) error {
4return nil
5}
6
7type MockEmailService struct {}
8
9func (m *MockEmailService) SendConfirmation(email string) error {
10return nil
11}
12
13func TestOrderProcessor() {
14mockDb:= &MockDatabase{}
15mockEmail:= &MockEmailService{}
16
17processor:= NewOrderProcessor(mockDb, mockEmail)
18err:= processor.ProcessOrder("TEST-001", "test@example.com")
19
20if err!= nil {
21fmt.Println("Test başarısız")
22} else {
23fmt.Println("Test başarılı")
24}
25}

Bu şekilde gerçek veritabanı ve e-posta servisi kullanmadan test edebilirsin. Constructor injection Go'da sadece bir desen değil, kodun bakımı ve genişletilmesi için pratik bir yol.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz