19.08.2017

TEK SORUMLULUK PRENSIBI

Nesne yönelimli gelistirme yaparken yazilan kodlarin tüm gelistiriciler tarafindan kolay okunabilmesi ve çözümlenebilmesi, yazilimin kaliteli ve hizli gelistirilebilmesi için izlenmesi gereken en önemli prensiplerden biridir.

Uzun süreye yayilan bir yazilimi gelistirmek oldukça zahmetli ve maliyetli bir istir. Bu çaptaki projelerde büyük kod yiginlari içinde kaliriz ve nerede ne yapildigini anlamak, sorunu tespit etmek, koda müdahale etmek biz yazilimcilar için genelde kâbus olur. Dolayisiyla bu tarz projelerde her zaman anlasilir ve temiz kodlar yazmak çok önemlidir.

Single Responsibility Principle(Tek Sorumluluk Prensibi), basit projelerde olsun yukarida tarif ettigimiz projelerde olsun önümüzü görmemizi, nesneleri ve nesne islevlerini(metotlari) rahatlikla anlamamizi saglayan bir yazilim gelistirme prensibidir. SOLIDprensipleri içerisinde ilk sirada yer alir. Bu prensibe uygun gelistirilmis projeler okunulabilirliligi yüksek oldugu için, ise sonradan dahil olan gelistiriciler projeye daha çabuk ve daha saglikli ayak uydururlar.

Bu prensibe göre bir metodun veya sinifin tek görevi olmalidir. Metot için konusursak, bir metoda yüklenen islev birden fazla olmamalidir. Örnegin bir ürünün fiyati güncellenip, ardindan magaza sorumlusuna e-posta atilacaksa ortada iki farkli metot olmalidir; birisi ürünün fiyatini güncelleyen(ör: UpdatePrice), digeri de e-posta gönderen(ör: SendMailToShopManager) metot olmalidir. Tek metot yazip hem ürün güncellemesi hem de e-mail gönderimiyle ilgili kodlarin tek metot içerisine konulmasi bu prensibe tamamen ters bir durum olur.

Sadece metot için degil sinif için de ayni durum geçerli. Örnegin kullanici ile ilgili islemleri yapan bir sinif içerisine sadece CreateUser, Login, ChangePassword gibi kullaniciyla ilgili metotlari eklemeliyiz. Böyle bir sinifa SendMail veya WriteLog gibi bir metot eklememek gerekir. Çünkü bu metotlar dogrudan kullaniciyla ilgili degildir. SendMail MailHelper, WriteLog da Logger gibi bir sinifin içerisinde yer almasi daha dogru olacaktir.

Yukaridaki resim bu prensibin önemini anlatiyor sanirim. Ilk bakista Isviçre çakisi herseyi üzerinde bulundurdugu için daha kullanisli gelebilir. Ama yazilim gelistirirken elimizden geldigince bilesenleri ayirmaliyiz, kimin ne yaptigi ve ne yapmadigi gibi konular ayristirilmali ve yazilim takimindaki herkes tarafindan iyice bilinmelidir.

Single Responsibility Principle uyumlu kod yazmak

SOLID’in ilk kurali olan single responsibility principle, yani tek sorumluluk prensibi yazilim gelistirirken yazdigimiz metodun, sinifin, hatta projenin tek bir sorumluluga sahip olmasini ve kendi alani disindaki farkli islemleri içermemesini bize ögütler. Bunu yapabilmek için her zaman kodu yazarken “bu islemi burada mi yapmaliyim?” “bu metot içerisinde birden fazla is yapiliyor mu?” “bu sinif x nesnesine hizmet etmek disinda farkli islevler içeriyor mu?” gibi sorular sorarak kod gelistirmeliyiz. Sadece kod gelistirirken degil, code review yaparken de baskasinin yazdigi metotlara ve siniflara içlerinde bu prensibe aykiri durumlar var mi gözüyle mutlaka bakmaliyiz. Degismesi gereken kisimlar için kodu yazan yazilimcinin gerekli düzeltmeleri yapmasini saglamaliyiz.

Bu prensibe uyarak yazdigimiz kodlari daha anlasilir hale getiririz. Proje ekibine yeni katilan biri dahi sinif isimlerinden ve metot isimlerinden nerelerde hangi islemlerin yapildigini kolayca anlar. Kod içindeki akislari takip etmek daha kolay olur ve bir islemle ilgili degisiklik yapilinca hem nereyi degistirecegimizi iyi biliriz, hem de sadece o islemin etki alanini degistirdigimizi biliriz.

Yine single responsibility principle uyumlu kod yazarsaniz diger prensiplere uyumunuzda kolaylasacak ve süre bakimindan daha esnekleseceksiniz. Çünkü kaliteli kod, artan zamana esittir. Ne kadar kaliteli kod yazarsaniz o kadar çok zaman kazanirsiniz.

?

 

Resim 1 deki gibi bir sinifa daha önce bir yerlerde rastlamissinizdir. Bu sinif kendisini bilgibankasina ekleme, silme, müsteriye email gönderme, login yapma (shop sistemi olabilir) ve siparis olusturma islemlerini yapabilmektedir.

 


Resim 1

Büyük bir ihtimalle bu sinifi programlayan programci kendisi ile gurur duyuyor olmalidir. Aslinda böyle bir sinifin ve programcinin küçümsenecek hiçbir tarafi yok. Bu sinif büyük emek harcanarak olusturulmus olabilir, çünkü ihtiva ettigi metotlar basit degildir. Lakin bu sinif saatli bir bombadir, çünkü içinde bulundugu ortamdaki her degisiklik, sinifin yapisal degisiklige ugramasina sebep olabilir. Bunun yani sira Customer sinifinda implemente edilen kod tekrar kullanilmak istendiginde, Customer sinifinin bagimli oldugu sinif ve API’lerin bu sinifla beraber kullanilma zorunlulugu vardir, yani Customer sinifi gittigi yere beraberinde kullandigi diger siniflar ve API’leri götürür. Bu kodun tekrar kullanimini saglamak için istenmeyen bir durumdur.

Customer sinifini test edilebilir ve bakimi kolay bir hale getirmek için, sahip oldugu sorumluluklarin baska siniflara yüklenmesi gerekmektedir. Bunun bir örnegini resim 2 de görmekteyiz.


Resim 2

Resim 2 de yer alan Customer sinifi sahip oldugu sorumluluklarin baska siniflara yüklenmesiyle hafiflemis ve degisikliklere karsi daha dayanikli bir hale gelmistir. Bunun yani sira bu sinifin test edilebilirligi yükselmistir. Bu ve diger siniflarin degismek için artik sadece bir sebebi vardir. Bunun sebebi sadece bir sorumluluk sahibi olmalarinda yatmaktadir.

Bir sinifin sorumlulugunu sadece bir sebepten dolayi degisebilir olmasi olarak tanimlayabiliriz. Eger bir sinifin degisiklige ugramasi için birden fazla sebep varsa, bu sinif birden fazla sorumluluk tasiyor demektir. Bu durumda sinifta sadece bir sorumluluk kalacak sekilde, sorumluklarin diger siniflarla paylasilmasi yoluna gidilmelidir.

Bu yaziyi PDF dosyasi olarak asagidaki linkten edinebilirsiniz.