Yazılım Tasarım Prensipleri – SOLID Prensipleri Nelerdir?

Yazılım Tasarım Prensiplerine Giriş

Tasarım Prensipleri bir yazılım projesinin ilerleyen dönemde sürdürülebilirliğini sağlayan en önemli yapı taşlarından biridir. Yazılım mimarileri hakkında detaylara inmeden önce Tasarım Prensiplerine hakim olmak çok yerinde olacaktır. Bu yazımızda tasarım prensipleri, yazılım tasarımı ve mimarisi dersleri için iyi bir kaynak sunmaya çalışacak; yazılım tasarım prensipleri nelerdir, solid tasarım prensipleri nelerdir gibi sorulara cevap vermeye çalışacağız.

En basit tabiriyle birbirinden farklı durumlarda, bir sorunu çözmek için kullandığımız açıklama ve şablonlara Yazılım Tasarım Prensipleri denir. Tasarım Prensipleri doğrultusunda yapılan sınıf tasarımları bir projede oluşabilecek değişimlerin projeye kolayca uyum sağlamasını sağlar.

Eğer projemizin tasarımı kötüyse, bu durum kolayca fark edilebilir. Eğer yeni bir istek veya değişiklik geldiğinde geliştirme ortamında her şeyin bozulacağına dair konuşmalar dönüyorsa yazılımınız kötü bir yazılım mimarisi ile tasarlanmış demektir.

Bir yazılım projesinde değişikliğin zor olması sınıfların birbiriyle sıkı yani composite bir ilişki içerisinde olduğunu gösterir. İyi tasarlanmış bir projede sınıflar birbirine gevşek bir ilişki içinde olmalıdır.

SOLID Tasarım Prensipleri – 5 Tasarım Prensibi

Yazılım geliştirme esnasında kullanılan 5 temel tasarım prensibi vardır. Bu prensiplerin baş harfleri SOLID kelimesini oluşturur. Sırasıyla Single Responsibly(Tek Sorumluluk), Open Closed(Açık Kapalı), Liskov Substitution(Liskov Yerine Geçme), Interface Segregation(Arayüz Ayrım) ve Dependency Inversion(Bağımlılığın Ters Çevrilmesi) prensiplerinden oluşur. Bu Solid tasarım prensipleri ayrı ayrı başlıklarda ele alacağız.

Tek Sorumluluk Prensibi – Single Responsibly Principle

Tek sorumluluk prensibi oluşturduğumuz sınıflara yada gruplara birden çok işlevi yerine getiren kompleks görevler vermek yerine tek ve özel bir görev tanımlamaktır. Bu sayede tekrar kullanılabilirlik oldukça artar ama tahmin edebileceğiniz gibi bu prensibi uygulamak oldukça zahmetli bir iştir.

Bir otomasyon yazılımda 3 farklı görevi tek başına yerine getiren bir rezervasyon sınıfı yerine, her biri yalnızca bir göreve sahip 3 farklı sınıf yaratmak tek sorumluluk prensibine örnek gösterilebilir.

Tek Sorumluluk Prensibi sayesinde kod tekrarının da önüne geçmiş oluruz. Sürekli tekrarlayan kod bloklarını tekrar tekrar yazmak yerine tek bir göreve sahip ayrı bir metod yazarak bu metodu farklı yerlerde kolayca kullanabiliriz. Herhangi bir değişiklik durumunda da tek bir adımda tüm değişikliği gerçekleştirebiliriz.

Açık Kapalı Prensibi – Open Closed Principle

Yazılım projeleri sürekli bir değişim içindedir. Sürekli olarak yeni istekler ortaya çıkar ve değişime ayak uydurmak için düzenlemeler yapmak gerekir. Açık kapalı prensibi de yazılım projemizde meydana gelen değişimleri sadece değişimin olduğu kısımda tutmamıza yarayan bir prensiptir. Örneğin bir otomasyon projesinde kullandığımız bir sınıfa yeni bir tedarikçi eklediğimizde yukarıdaki sınıfta değişiklik yapmamız gerekmiyorsa bu açık kapalı prensibine uygundur.

Bu prensibe göre kodlarımız değişime kapalı fakat gelişime oldukça açık bir duruma gelmektedir. Yani gereksiz değişimlerden ve yaptığımız değişimleri diğer class yapılarına sıçratmak sorunundan uzak ama gelişime fazlasıyla açık bir yapı kuruyoruz.

Açık kapalı prensibini uygulamak için sınıflar arasına interface yani arayüz koyarak sınıflar arasındaki bağı gevşek hale getirebiliriz.

Bağımlılığın Ters Çevrilmesi Prensibi – Dependency Inversion Principle

Eski yazılım geliştirme mantığına göre üst seviyede işlem yapan yazılım metodlarımız, alt seviyedeki metodlara bağımlı haldedir. Bu durumda sınıflar birbirine sıkı bir şekilde bağlı olduğu için metodların tekrar kullanılması çok zor bir hal almaktadır. Bağımlılığın ters çevrilmesi metoduyla araya bir soyutlama koyarak alt seviye bir sınıfı üst seviye bir sınıfa bağımlı hale getiririz.

Bağımlılığın Ters Çevrilmesi Prensibi ile araya interface koyduğumuzda alt sınıfın ezmek zorunda olduğu metodlar belli olur ve bu sayede amiyane tabirle alt sınıflar kafasına göre takılamaz diyebiliriz.

Önemli: Bir Proje bağımlılığın ters çevrilmesi prensibine uyuyor diye open-close prensibine de uymak zorunda değildir.

Bağımlılığın Ters Çevrilmesi Prensibine Uyarken Açık Kapalı Prensibine Uymama Durumu

Örneğin bir ticaret otomasyonu projemizde sistemimizde iki farklı tedarikçi yer alıyor. Bu tedarikçiler arasına bir tedarikçi daha eklemek istiyoruz ama bir sorun var. Eklemek istediğimiz 3. Tedarikçi yurtdışı tedarikçisi olduğu için diğerlerinden farklı özelliklere sahip. Böyle bir durumla karşılaştığımızda yapacağımız ilk iş bir üst sınıfa gidip, sınıfın işleme aldığı tedarikçilerin yurtiçi mi yurtdışı mı olduğunu kontrol eden bir kod bloğu yerleştirmek olacaktır. Böyle bir durumda Dependency Inversion uyumlu fakat Open-Close uyumsuzdur deriz.

Arayüz Ayrım Prensibi – Interface Seggregeation Principle

Projemizde kullandığımız bir arayüze haddinden fazla yetenek yüklediğimizde o arayüzden implemente edilen alt sınıflar için problemler ortaya çıkabilir. Bu durumda alt sınıflarda teoride sahip olunan ama pratikte kullanılmayan özellikler yer alacaktır. Arayüz ayrım prensibi ile bu tasarım hatasının önüne geçmeye çalışırız.

Bir araca sahip olmadığı bir özelliğin tuşunu koymak ama bu tuşu işlevsiz bırakmak bu duruma örnek gösterilebilir.

Bir diğer örnek de bir bankacılık sisteminde iki farklı metod kullanan bankalar olduğunu düşünelim. Bankalardan birisi ise sadece tek bir metoda sahiptir. Böyle bir durumla karşılaştığımızda eğer iki metodu da sadece bir arayüzden implemente ediyorsak tek metoda sahip bankada bir metodun davranışını boş tanımlamamız gerekecektir. Bu durumda boş olarak tanımlanan 2. Metod da bu bankanın nesnesini oluştururken karşımıza çıkacaktır. Bu iyi bir tasarım şekli değildir. Metodlar için farklı arayüzler oluşturabilir ve ihtiyaçlarımıza göre birbirinden kalıtım almasını sağlayabiliriz. Bu sayede arayüz ayrım prensibine uygun bir tasarım elde etmiş oluruz.

Liskov’un Yerine Geçme Prensibi – Liskov Substitution Principle

Liskov’un Yerine Geçme Prensibi yazılımcılar arasında “Dummy Koda Hayır” prensibi olarak da bilinmektedir. Prensibin amacı yarattığımız alt sınıfların üst sınıflarda tanımlanan tüm işlevleri tam olarak yerine getirmesidir. Arayüz ayrım prensibinde bahsettiğimiz işlevsiz metodlar, Liskov’un yerine geçme prensibine de aykırıdır.

Bu prensip için kısaca üst sınıflar ve alt sınıflar arasında davranış farklılığı bulunmamalıdır diyebiliriz. Yani alt sınıf yerine üst sınıfı da kullandığımızda herhangi bir farklık ortaya çıkmamalıdır. Child class kullanırken bir anda parent sınıf kullanabilmeli ve yolumuza herhangi bir problemle karşılaşmadan devam edebilmeliyiz.

 

 

Bir cevap yazın

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