DIP'i İhlal Eden Durum

Mustafa Çam - Mar 5 - - Dev Community

Senaryo: E-posta Gönderme İşlemi

Bir EmailService sınıfımız olsun ve bu sınıf doğrudan bir somut sınıf olan SmtpClient'a bağımlı olsun. Bu durumda, SmtpClient'ı değiştirmek ya da farklı bir e-posta gönderme servisi eklemek istediğimizde, EmailService sınıfında değişiklik yapmak zorunda kalırız.

1. DIP'yi İhlal Eden Durum (Sıkı Bağlantı)

public class EmailService
{
    private SmtpClient _smtpClient;

    public EmailService()
    {
        _smtpClient = new SmtpClient();  // Direkt olarak SmtpClient'a bağlı.
    }

    public void SendEmail(string to, string subject, string body)
    {
        _smtpClient.Send(to, subject, body);
    }
}

public class SmtpClient
{
    public void Send(string to, string subject, string body)
    {
        Console.WriteLine($"E-posta gönderildi: {to}, {subject}, {body}");
    }
}
Enter fullscreen mode Exit fullscreen mode

Sıkı Bağlantı Sorunu:

Şu anki yapımızda, EmailService sınıfı doğrudan SmtpClient sınıfına bağlıdır. Bu durumda, EmailService'in işlevselliğini değiştirmek istesek (örneğin, e-posta gönderme yöntemini değiştirmek veya başka bir e-posta servisi kullanmak gibi), EmailService sınıfında mutlaka değişiklik yapmamız gerekir.

Diyelim ki, yeni bir SendGridEmailClient eklemek istiyoruz ve EmailService'in SmtpClient'a olan bağımlılığını değiştirmemiz gerekiyor.

2. Değişiklik Yapma Zorunluluğu (Bağımlılıklar Sıkıdır)

Eğer EmailService doğrudan SmtpClient'a bağlıysa ve biz SendGrid kullanmaya karar verirsek, o zaman EmailService sınıfını değiştirmemiz gerekecek.

public class SendGridEmailClient
{
    public void Send(string to, string subject, string body)
    {
        Console.WriteLine($"E-posta gönderildi (SendGrid): {to}, {subject}, {body}");
    }
}

public class EmailService
{
    private SendGridEmailClient _sendGridEmailClient;

    public EmailService()
    {
        _sendGridEmailClient = new SendGridEmailClient();  // SendGrid'e geçiş yapıyoruz.
    }

    public void SendEmail(string to, string subject, string body)
    {
        _sendGridEmailClient.Send(to, subject, body);
    }
}
Enter fullscreen mode Exit fullscreen mode

Değişiklikler:

  • EmailService'i değiştirmek zorunda kaldık çünkü SmtpClient'a olan bağımlılığı doğrudan yerleştirmiştik.
  • Ayrıca EmailService'i test etmek ya da başka bir servise entegre etmek için bu tür bağımlılıkları değiştirmeniz gerekecek.

3. DIP'yi Uygulayan Durum (Esnek ve Soyutlamalı)

Eğer DIP'yi uygularsak, EmailService sadece bir soyutlama olan IEmailClient'e bağlı olur ve somut sınıflar (SmtpClient, SendGridEmailClient) daha esnek bir şekilde değiştirilebilir.

public interface IEmailClient
{
    void Send(string to, string subject, string body);
}

public class SmtpEmailClient : IEmailClient
{
    public void Send(string to, string subject, string body)
    {
        Console.WriteLine($"E-posta gönderildi (SMTP): {to}, {subject}, {body}");
    }
}

public class SendGridEmailClient : IEmailClient
{
    public void Send(string to, string subject, string body)
    {
        Console.WriteLine($"E-posta gönderildi (SendGrid): {to}, {subject}, {body}");
    }
}

public class EmailService
{
    private readonly IEmailClient _emailClient;

    // Dependency Injection ile bağımlılık ekleniyor.
    public EmailService(IEmailClient emailClient)
    {
        _emailClient = emailClient;
    }

    public void SendEmail(string to, string subject, string body)
    {
        _emailClient.Send(to, subject, body);
    }
}
Enter fullscreen mode Exit fullscreen mode

Esneklik Kazanma:

  • Şimdi, EmailService sınıfı sadece soyutlama olan IEmailClient'a bağlıdır.
  • EmailService'i değiştirmek zorunda kalmadan, farklı bir e-posta servis sağlayıcısı kullanabiliriz. Mesela SendGridEmailClient veya SmtpEmailClient gibi servisleri sadece IEmailClient'i implement eden sınıfları sağlayarak değiştirebiliriz.
public class Program
{
    public static void Main()
    {
        IEmailClient emailClient = new SendGridEmailClient();  // Ya da SmtpEmailClient
        var emailService = new EmailService(emailClient);

        emailService.SendEmail("test@example.com", "Konu", "E-posta içeriği");
    }
}
Enter fullscreen mode Exit fullscreen mode

Sonuç:

  • DIP'yi ihlal ettiğimizde, EmailService sınıfını değiştirmek zorunda kalırız çünkü doğrudan somut sınıfa bağımlıdır. Yeni bir e-posta servisi eklediğimizde, bu servisin işlevini değiştirebilmek için EmailService'i de güncellememiz gerekir.

  • DIP'yi uyguladığımızda, soyutlamalar sayesinde EmailService sınıfını değiştirmeden yeni bir e-posta servisi ekleyebiliriz. Yüksek seviye modüller (iş mantığı) ve düşük seviye modüller (somut sınıflar) arasında bağımlılık yoktur, sadece soyutlama üzerinden iletişim vardır. Bu da daha esnek ve bakım kolaylığı sağlar.

Bu şekilde, bağımlılıkların sıkı olduğu durumlarda, değişiklik yaparken diğer sınıflarda da değişiklik yapmanız kaçınılmaz hale gelir. DIP, bu tür sorunları önleyerek yazılımın daha sürdürülebilir ve esnek olmasını sağlar.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .