Tek Sorumluluk Prensibi (SRP – Single Responsibility Principle)

Bugünkü yazımda daha önce bahsetmiş olduğum yazılım tasarım prensiplerinden (SOLID) tek sorumluluk prensibi (single responsibility principle) üzerinde duracağım. Yukarıdaki görselde görüleceği gibi bazı durumlarda içerisinde birçok işlev barındıran sınıflar (class) aynı bir isviçre çakısı gibi size pratiklik sağlayabilir. Fakat işler büyümeye ve daha karmaşık hale gelmeye başladığında bu işlevler güçsüz kalmaya ve sizi bazı noktalarda kilitlemeye başlar.

Bu konuyu basit bir şekilde örneklendirecek olursak loglama, mail gönderme ve kimlik doğrulama işlemlerini kendi üzerine toplamış bir sınıf kodlayabiliriz.

public class Siparis
{
    public void SiparisKaydet()
    {
        if (KimlikDogrula())
        {
            try
            {
                 // Sipariş kaydetme işlemleri burada yapılıyor

                 MailGonder("Siparişiniz başarı ile kaydedildi", ...);
            }
            catch (Exception e)
            {
                 Log("Sipariş kaydedilirken hata oluştu.", e, ...);
            }
        }
    }

    public bool KimlikDogrula()
    {
        // Kimlik doğrulama ile ilgili işlemler...
    }

    public void MailGonder(string mesaj, ...)
    {
        // Mail gönderimi ile ilgili işlemler...
    }

    public void Log(string mesaj, Exception e, ...)
    {
        // Loglama ile ilgili işlemler...
    }
}

Yukarıdaki örnekte görüleceği üzere sipariş sınıfımız, siparişi kaydetmenin yanı sıra siparişi kaydeden kişinin kimlik doğrulama işlemleri, sipariş kaydedildiğinde ilgililere mail gönderilmesi ve eğer bir hata ile karşılaşılırsa çıkan hatanın loglanması gibi fazladan bir takım görevler de üstlenmiş durumda. Bu fazladan görev üstlenme durumu bizim sipariş sınıfımızı olması gerekenden daha kalabalık bir hale getirdiği gibi, kimlik doğrulama, mail gönderimi ve loglama işlemlerinin diğer sınıflarda kullanılmasını engelleyerek kod tekrarlarına neden olmaktadır.

Şimdi bu örneği tek sorumluluk prensibine (single responsibility principle) göre böldüğümüzde oluşacak yeni halini aşağıya kodlayalım.

public class Siparis
{
    public void SiparisKaydet()
    {
        if (GuvenlikIslemleri.KimlikDogrula())
        {
            try
            {
                 // Sipariş kaydetme işlemleri burada yapılıyor

                 MailIslemleri.MailGonder("Siparişiniz başarı ile kaydedildi", ...);
            }
            catch (Exception e)
            {
                 LoglamaIslemleri.Log("Sipariş kaydedilirken hata oluştu.", e, ...);
            }
        }
    }
}

// Diğer sınıfları static olarak tanımladım. Projenin genel yapısına göre bu durum değişebilir.

public static class GuvenlikIslemleri
{
    public static bool KimlikDogrula()
    {
        // Kimlik doğrulama ile ilgili işlemler...
    }
}

public static class MailIslemleri
{
    public static void MailGonder(string mesaj, ...)
    {
        // Mail gönderimi ile ilgili işlemler...
    }
}

public static class LoglamaIslemleri
{
    public static void Log(string mesaj, Exception e, ...)
    {
        // Loglama ile ilgili işlemler...
    }
}

Bu örnekte görüldüğü üzere sipariş sınıfımız artık sipariş ile ilgili olmayan kimlik doğrulama, mail gönderme ve loglama işlemlerini kendi içinde barındırmıyor, bu işlemler için ilgili diğer sınıflardaki metotları çağırıyor. Bu şekilde sipariş sınıfımız sadece kendi işini yapan sade bir sınıf haline geldi, kod kalabalığından arındı. Ayrıca diğer işlemler de ayrı sınıflar içerisine taşındığından projenin her yerinde kullanılabilir duruma geldi ve böylece kod tekrarının da önüne geçilmiş oldu.

Faydalı olması dileğiyle…

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir