
Yazılımın anlaşılır, yeniden kullanılabilir, esnek olmasını ve kod tekrarını da önlememizi sağlayan prensiplerdir. Geliştirdiğimiz yazılım ile ilgili, veya bir başkasının geliştirdiği bir yazılım ile ilgili ilerleyen zamanlarda bir güncelleştirme yapmamız gerektiğinde karmaşık kod yapısında zorlanabiliriz işte bu noktada SOLID prensipleri ile yazılmış bir projede işlerimiz daha da kolaylaşıyor. Ayrıca geliştirdiğimiz kodun esnek ve geliştirilebilir şekilde tasarlanmaması ileride yapacağımız entegrasyonlar veya geliştirmeler bakımından bizi kısıtlayacaktır.
Şimdi gelelim 5 harfli SOLID kısmına, isminden de anlaşılacağı üzere baş harflerinden oluşan 5 farklı prensipten oluşur.
- Single Responsibility Principle (SRP)
- Open Closed Principle (OSP)
- Liskov Substitution Principle (LSP)
- Interface Segregation Principle (ISP)
- Dependency Inversion Principle (DIP)
Single Responsibility Principle (Tek Sorumluluk Prensibi)
İsminden de anlaşılacağı üzere her metot ve sınıfın tek bir görevi ve sorumluluğu olmalıdır. Aşağıda buna bir örnek verelim;
Aşağıdaki örnekte Personel sınıfı hem Maaş hem de Personel işlemlerini yapmaktadır. Bu SOLID prensiplerine uygun değildir.

Aşağıdaki örnekte olduğu gibi yaparsak SOLID prensiplerine uygun şekilde yapmış oluruz. Aşağıda gösterilen örnekte 2 ayrı sınıfta fiyat ve arac sınıfı tanımladık ve metotlarını da sadece kendi sınıfı içerisinde tanımladık. Bu şekilde SOLID prensiplerine uygun şekilde tasarlamış oluruz.


Aşağıda buna bir örnek daha verecek olursak;

Open Closed Principle (Açık Kapalı Prensibi)
Bu prensibe göre her sınıf gelişime açık fakat değişime kapalı olmalıdır. Yani açıklayacak olursam bir projeye eğer güncelleme yapmak istiyorsak eski kodun çalışmasını bozmadan üzerine entegrasyon yapmalıyız. Aksi halde eski kodu bozabiliriz. Buna bir proje içerisinde örnek vermek gerekirse,

Buna daha farklı bir örnek te verebiliriz;
Şimdi aşağıdaki örnekte AracEkle metodunu parametredeki markaya göre defalarca kez koşul vererek ekledik.

Ancak yukarıdaki kod kötü bir görünüme sebep olacaktır. Bu nedenle bunu Açık Kapalı Prensip (Open Closed Principle) ile aşağıdaki gibi yapabiliriz.

Yukarı görüldüğü üzere Arac abstract sınıfından AracEkle metodunu oluşturduğum araç sınıflarına implemente ettim ve override ederek metodu ezdim. Daha sonra ise kullanmak istediğim kodları bu kısımlara yazabilirim.
Görüldüğü üzere son kısımda daha göze düzgün gelen ve anlaşılır bir yapı kurmuş olduk.
Liskov Substitution Principle (Liskov’un Yerine Geçme Prensibi)
Bu konuyu araştırırken birçok farklı kaynak ve yazı inceledim. Birçok yazıyı ve kaynağı bir arada bulundurduğunu düşündüğüm yazıyı buradan bulabilirsiniz.
Şimdi gelelim benim bakış açıma göre bu konuyu nasıl anladığıma,
Herkes bu konuya örnek verirken birşeyin özellikleri üzerinden gitmiş mesela yukarıda belirttiğim linkteki yazıda uçakların özellikleri üzerinden gitmiş keşif yap ve hedefi vur özellikleri ile. Bazı uçaklar bu iki özellikten sadece birine sahipken bazıları ikisine de sahip.
Başka denk geldiğim bir örnekte ise bir bir futbol takımında kaleci ve forvet özellikleri üzerinden gidiyor. Bir forvet topa vurabilirken eli ile topu tutamaz. Ancak bir kaleci hem topa vurabilir hem de topu eli ile tutabilir. Bu da güzel bir örnek. Şimdi ise kendim bir örnek türetmeye çalıştım.
Ben yeniden araç örneği üzerinden gitmek istiyorum.




Yukarıda da görüldüğü üzere derived class içerisinde implemente edilen tüm metotlar kullanılmamıştır. Ama IArac interface’i bunu uygulatmak zorundadır. Kullanılmayan metotlar Dummy Code yapısındadır. Kullanılmayacak metotları if yapısı kullanarak çözebiliriz ancak bu yapı karışık olmakla birlikte Open Closed Principle’a terstir.

Yani ana yapıya müdahale etmiş oluruz. Bu nedenle aşağıdaki şekilde yaparsak hem OCP’ye uymuş olacağız hem de LSP prensibini uygulamış olacağız.
Burada base class olan yolculuk sınıfının tüm işlevlerini farklı arayüzlere bölüyorum.




Yukarıdaki örnekte herhangi bir kontrole gerek kalmadan istediğimiz kadar araç markası ekleyip istediğimiz özelliği verebiliriz. Genel olarak bu prensipten anladıklarım bu şekilde, tabi örnekler şekillendirilebilir. Herkesin anlayış biçimi ve algısı farklı çalışıyor o nedenle bunu kendi mantığınızla bir örnek oluşturarak harmanlarsanız çok daha anlaşılır olacaktır.
Interface Segregation Principle (Arayüz Ayrım Prensibi)
ISP mantığında her farklı yetenek için farklı bir arayüz tanımlarız. Yukarıda buna biraz benzer bir örnek vermiş olduk sanırım. Burada ISP ile gereksiz metot ve kodların implemente edilmesinin önüne geçmeye çalışıyoruz.
Bir örnek ile devam edelim.
Yine araç örneği üzerinden devam edeceğim. Aşağıda görüldüğü üzere 3 farklı marka için sınıf oluşturdum. Mesela Opel araç için klima ve hız sabitleyici özellikleri var ancak otomatik park özelliği yoktur. Ancak ben burada otomatik park metodunu da gereksiz yere kullanmış oldum. Aynı şekilde bu gereksiz kullanım diğer Renault markası için de geçerlidir.



Bu kullanımın önüne ISP (Interface Segregation Principle) ile geçeceğiz. Her bir özelliği ayrı interface olarak alırsak problem çözülmüş olacaktır.



Dependency Inversion Principle (Bağımlılığın Ters Çevrilmesi Prensibi)
Tasarladığımız kodun bağımlılığı implementation(uygulama) sınıflara değil interface(arayüz)’lere olmalıdır. Üst seviyeli işlem yapan sınıflar alt seviyeli işlem yapan sınıflara bağımlı olmaktadırlar. Bununla birlikte alt seviye metodlardaki değişiklikler üst seviye metodlarda değişikliğe sebep olur. DIP bize bu bağımlılığın tersine çevrilmesini önermektedir.
Örnek üzerinden gidecek olursak,
Aşağıdaki örnekte Uretim sınıfı Araba sınıfının ArabaUret metoduna bağımlıdır. Bu metotlarda yapılacak herhangi bir değişiklik direkt olarak Uretim sınıfı içerisinde de değişiklik gerektirecektir.

Sınıf diyagramını da inceleyelim.

Şimdi DIP prensibine göre düzenlersek;


Alt seviye sınıfımızı interface ile soyutlaştırarak üst seviye sınıfımızda alt seviye sınıfa olan bağımlılığını tam tersine çevirmiş olduk. Alt seviye sınıfımız, Interface’e bağımlı bir hale gelmiştir. Alt sınıfımız ilgili Interface’de üst seviye sınıf tarafından referans alındığından dolaylı bağımlılık alt seviyeden üst seviyeye doğrudur.