Tek Sorumluluk Prensibi(Single Responsibility Principle – SRP)
Merhaba,
Dünya üzerinde genel geçer kabul görmüş ve SOLID prensipleri diye nitelendirilen beş adet tasarım deseninden ‘S‘ si olan Tek Sorumluluk Prensibi – Single Responsibility Principle (SRP)’yi izah etmeye çalışacağım.
Nesne Tabanlı Programlama yaklaşımında temel unsur sınıf yapılarıdır. Bir proje inşa sürecinde sınıflar inşaatın her bir katmanında kendilerine has görev icra eden işçilerdir. Eğer bu işçilere birden fazla görev yüklenirse(ki biz bu görevlere sorumluluk diyeceğiz) ne kadar verim alınabileceğini düşünmenizi isterim. Evet, basit mantık düşünelim. Bir inşaat işçisine bir yandan duvarı örme ve bir yandan da tesisatı döşeme işini verirseniz bu iki işin güvenirliğini aklen ne kadar tasdik edebiliriz?
İşte OOP yapılarındaki elemanlarımızında üstleneceği görevler sade ve sadece bir adet olmalıdır.
Yani dahada açarsak eğer,
Her sınıf ve metod sade ve sadece ‘Tek Bir Sorumluluğu’ yerine getirmelidir.
İşte tek sorumluluk prensibi bu manada şekillenmiştir.
Bir sınıf yahut metoda baktığımız zaman sorumluluk olarak genelde o sınıf yahut sınıf içerisindeki bir metod işlevi akla gelmekte, bu işlev sorumluluk(görev) olarak nitelendirilmektedir. Halbuki sizde bilirsiniz ki, çoğu sorumluluk birden fazla sınıf ve metod eşliğinde yerine getirilmektedir.
O halde sorumluluk algımızı değiştirmeli ve aşağıdaki gibi olgunlaştırmalıyız.
Bir sınıfın yahut metodun sorumluluğu, değişmesi için bulunan sebebidir.
Anlayacağımız o ki, bir sınıfın veya metodun sorumluluk olarak bağlılığı kendisini değiştirmeye iten sebepleridir. O yapı ne kadar değişme sebebi arz ediyorsa o kadar sorumluluğu var demektir.
Tek Bir Sorumluluğu yerine getirmek demek, ilgili sınıf ya da metodun değişmek için sade ve sadece bir sebebinin bulunması demektir.
Eğer ki bir sınıf üzerinde iki ayrı işi yapıyorsanız iki ayrı değişiklik sebebiniz var demektir. Aslında bu iki ayrı iş için iki ayrı sınıfın olması gerçeğiyle yüzleşmek demektir.
Elinizde 1000+ satırlık bir sınıfınız mevcutsa büyük ihtimal bu prensibi çiğniyorsunuz demektir.
Şimdi SRP’ye özel bir örneklendirme yapalım.
Örneklendirmemiz bir alışveriş senaryosu üzerinden seyr edecektir. Alışveriş esnasında kredi kartıyla yapılacak ödemeye özel iki adet işlem örneklendireceğiz. Bunlar, limit kontrolü ve ödemenin gerçekleştirilmesidir. Şimdi aşağıdaki kod bloğunu inceleyiniz.
class AlisVeris { public double UrunFiyati { get; set; } public bool LimitYeterliMi() { . . . return true; } public bool AlisVerisTamamla() { . . . return true; } }
Evet, gördüğünüz gibi bu iki işlemi tek bir sınıf içerisinde yaparak SRP’yi çiğnemiş olduk. Çünkü limit kontrolü ile alişverişi tamamlama işlemleri birbirlerinden farklı işlemlerdir. Yapmamız gereken bu işlemlere özel sınıflar oluşturmaktır.
class LimitKontrol { public bool LimitYeterliMi() { return true; } } class AlisVerisYapici { public bool AlisVerisTamamla() { return true; } } class AlisVeris { public double UrunFiyati { get; set; } }
Yaptığımız bu işlemlerin class diyagramlarınıda inceleyerek olayı somutlaştıralım.
SRP’ye Aykırı | SRP’ye Uygun |
Projemizi bu şekilde kodladığımızda binlerce satırlık metodlar ve sınıflardan arındırmış olmakla beraber, bir sınıfın değiştirilmesi sebebini bire indirgemiş oluruz. Kodumuz okunabilir, anlaşılabilir ve gönül rahatlığıyla müdahale edilebilir bir disiplinde olacaktır.
Tabi ki de bu prensip karışıkları önlemek ve anlaşılabilirliği arttırmak açısından da önem teşkil etmektedir. Ancak küçük çaplı projelerde bu prensibi uygulamak faydadan çok zulme girebilir. Nihayetinde yapacağınız işin boyutuna göre hamlenizi tasarlayarak, o tasarıma göre uygun prensipleri ve desenleri faaliyete sokmak daha maliyetli olacaktır.
Okuduğunuz için teşekkür ederim.
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim.
Slmlar ,
Yazınız icin tesekkurler.Yalnız verdiginiz ornekte su konuyu merak ediyorum. Interface Segregation Principle ; aynı işin yapan metod tanımının aynı interface de olması gerektigini soyluyor.Simdi sizin orneginizde AlışVeriş aksiyonlarını içeren birden fazla method aynı interface de tanımlanacaksa ve bu interface terk bir sınıfa implemente edilecekse , SRP orneginiz nasıl yapılanacaktı ?
Tesekkurler.
Merhaba,
Prensiplerde asıl amaçlardan birisi dummy code dediğimiz kullanılmayan kodları ortadan kaldırmak olduğu hedeflendiği için prensipler çerçevesinde hareket etmekteyiz.
Bir çalışma, bir veya birden fazla prensibi barındırabilir. Haliyle ISP’ye bakarsak eğer bir interface ihtiyaca dönük fazla ya da az geliyorsa bizlere bu interface yapısını parçalayabilme hakkı tanımaktadır. Bu konu hakkında ilgili prensibin makalesinde detaylıca anlatımda bulunduğumu varsayıyorum. Ama şunu unutmayın ki; ISP dediğiniz gibi aynı işi yapan metotları aynı interface de olması gerektiğini savunmamakta, benzer işlevler bir arada tutulmasını lakin her farklı yetenek için farklı bir arayüz tanımlamasını önermektedir.
SRP bir sınıfa tek sorumluluk yüklerken, ISP ile farklı arayüzlere ayrılmış her bir yetenek SRP ile uygun bir şekilde çalışacaktır. Burada ISP her bir yeteneği tek bir sınıfa yüklemektense, ayrı ayrı sınıflara atayarak SRP’ye de uymuş olacaktır.
Sevgiler…