Single Responsibility Prensibi

Herkese merhaba, C# yazılarımıza kaldığımız yerden devam ediyoruz. Bu yazımızda SOLID prensiplerinden olan Single Responsibility Prensibi’ni anlatacağım. Hadi başlayalım !
Table of Contents
Ben yazıyı C# kategorisi altında yazdım ve birazdan vereceğim kod örnekleri de C# diliyle olacaktır fakat Single Responsibility Prensibi C#’a özgü bir kavram değil, nesne tabanlı programlamaya özgü bir kavramdır. Yani Java, Python, Visual Basic gibi nesne tabanlı dillerde de Single Responsibility Prensibi’ni uygulayabilirsiniz.
Single Responsibility Prensibi (SRP) yazılım geliştirme dünyasında oldukça önemli bir prensiptir. SRP, bir sınıfın yalnızca bir sorumluluğu olması gerektiğini belirtir. Bu, bir sınıfın yalnızca bir işlevi yerine getirmesi gerektiği anlamına gelir. Bu şekilde, sınıfların ve modüllerin daha az bağımlı hale gelmesi, kodun daha okunaklı ve daha sürdürülebilir hale gelmesi sağlanır.
C# gibi nesne yönelimli programlama dilleri, SRP’nin uygulanmasını kolaylaştırır. C#’ta, bir sınıfın yalnızca bir sorumluluğu olması gerektiği anlayışı üzerine kodlanabilir. Aşağıdaki örnekler, SRP’nin C# dilinde nasıl uygulanabileceğine dair örnekler sunar.
Örnek 1: Birden Fazla Sorumluluk Yüklenen Sınıf
Aşağıdaki örnek, bir “Kullanıcı” sınıfının, hem kullanıcının bilgilerini içermesini, hem de kullanıcının hesap bilgilerini yönetmesini gösterir.
public class Kullanici
{
public string Adi { get; set; }
public string Soyadi { get; set; }
public string Email { get; set; }
public string Sifre { get; set; }
public bool GirisYap(string email, string sifre)
{
// giriş işlemleri
}
public bool KayitOl(Kullanici kullanici)
{
// kayıt işlemleri
}
}
Bu örnek, SRP’ye uymaz. Çünkü “Kullanıcı” sınıfı, kullanıcının bilgilerini içermesi ve hesap bilgilerini yönetmesi için iki ayrı sorumluluk taşır. Bu nedenle, sınıfın daha fazla sorumluluk yüklemesi, kodun daha karmaşık hale gelmesine ve sınıfın daha az esnek olmasına neden olabilir.
Örnek 2: SRP’ye Uygun Kodlama
Aşağıdaki örnek, SRP’nin uygulanması için “Kullanici” sınıfının iki ayrı sınıfa ayrılmasını gösterir.
public class KullaniciBilgileri
{
public string Adi { get; set; }
public string Soyadi { get; set; }
public string Email { get; set; }
}
public class KullaniciIslemleri
{
public bool GirisYap(string email, string sifre)
{
// giriş işlemleri
}
public bool KayitOl(KullaniciBilgileri kullaniciBilgileri, string sifre)
{
// kayıt işlemleri
}
}
Bu örnekte, “KullaniciBilgileri” sınıfı, kullanıcının bilgilerini içeren bir veri sınıfıdır. “KullaniciIslemleri” sınıfı ise, kullanıcı işlemlerinin gerçekleştirildiği bir işlem sınıfıdır. Böylece, her sınıfın yalnızca bir sorumluluğu vardır ve her sınıf, sadece kendi işlevleriyle ilgilenir.
Bu şekilde, kodun daha okunaklı hale gelmesi ve daha sürdürülebilir olması sağlanır. Ayrıca, her sınıfın kendi işlevi için farklı zamanlarda değiştirilebilir olması, kodun daha esnek hale gelmesini sağlar.
Örnek 3: SRP ve Dependency Injection (Bağımlılık Enjeksiyonu)
Bağımlılık Enjeksiyonu (Dependency Injection – DI), SRP’ye uygun kodlama ile birleştirildiğinde, daha esnek ve test edilebilir bir kod tabanı elde edilebilir. DI, bir sınıfın bağımlılıklarının, sınıfın kendisi tarafından enjekte edilmesi yerine, dışarıdan bir kaynaktan (örneğin, bir IOC kütüphanesi) enjekte edilmesi anlamına gelir.
Aşağıdaki örnek, DI kullanarak, SRP’ye uygun kodlama ile birleştirilmiş bir “KullaniciIslemleri” sınıfını gösterir:
public interface IKullaniciRepository
{
bool KayitOl(KullaniciBilgileri kullaniciBilgileri, string sifre);
}
public class KullaniciIslemleri
{
private readonly IKullaniciRepository _kullaniciRepository;
public KullaniciIslemleri(IKullaniciRepository kullaniciRepository)
{
_kullaniciRepository = kullaniciRepository;
}
public bool GirisYap(string email, string sifre)
{
// giriş işlemleri
}
public bool KayitOl(KullaniciBilgileri kullaniciBilgileri, string sifre)
{
return _kullaniciRepository.KayitOl(kullaniciBilgileri, sifre);
}
}
Bu örnekte, “KullaniciIslemleri” sınıfı, DI kullanarak bir “IKullaniciRepository” bağımlılığı alır. Bu sayede, bağımlılıkların sınıf içinde enjekte edilmesi yerine, DI kütüphanesi tarafından enjekte edilir.
Bu örnekte, “KullaniciIslemleri” sınıfı, yalnızca kullanıcı işlemleri için sorumluluk taşır. “IKullaniciRepository” arabirimi, kullanıcının kaydedilmesiyle ilgili sorumluluğu taşır. Bu şekilde, her sınıf yalnızca bir sorumluluğa sahip olur ve kod daha esnek ve test edilebilir hale gelir.
Single Responsibility Prensibi yazılım geliştirme sürecinde çok önemlidir. Bu prensip, her sınıfın yalnızca bir sorumluluğa sahip olması gerektiğini vurgular. Böylece, kod daha okunaklı, daha sürdürülebilir ve daha esnek hale gelir.
Single Responsibility Prensibi Uygulama Yöntemleri
Single Responsibility Prensibi’ne uygun kodlama yapmak için şu adımlar izlenebilir:
- Sınıfları küçük tutmak ve yalnızca bir sorumluluğu olan sınıflar oluşturmak.
- Her sınıfın sorumluluğunu açık bir şekilde belirlemek.
- Sınıflar arasındaki bağımlılıkları azaltmak.
- Bağımlılık Enjeksiyonu kullanmak.
Yukarıdaki örneklerde de görüldüğü gibi, SRP’ye uygun kodlama yapmak için birçok farklı yaklaşım kullanılabilir. Önemli olan, her sınıfın yalnızca bir sorumluluğa sahip olması ve bu sorumluluğu açık bir şekilde belirlemektir.
Sonuç
Sonuç olarak, Single Responsibility Prensibi yazılım geliştirme sürecinde çok önemlidir ve C# programlama dilinde bu prensibe uygun kodlama yapmak, daha okunaklı, daha sürdürülebilir ve daha esnek bir kod tabanı oluşturmak için gereklidir.
Tüm C# yazılarımıza buraya, diğer SOLID prensipleri ile ilgili yazılarımıza buraya tıklayarak ulaşabilirsiniz. Herkese hayırlı günler.