SOLID

**SOLID**, nesne yönelimli programlama ve yazılım tasarımı için önerilen beş temel prensibin baş harflerinden oluşan bir kısaltmadır. Bu prensipler, yazılımın daha anlaşılır, esnek, sürdürülebilir ve bakımı kolay olmasını sağlamayı amaçlar. SOLID prensipleri, Amerikalı yazılım mühendisi ve eğitmen Robert C. Martin tarafından ilk olarak 2000 yılında yayımlanan "Tasarım İlkeleri ve Tasarım Modelleri" (*Design Principles and Design Patterns*) makalesinde tanıtılmıştır.

"**SOLID**" kısaltması, 2004 yılı civarında Michael Feathers tarafından, Robert C. Martin'in ilkelerini sistematik biçimde adlandırmak üzere önerilmiştir.

Bu ilkeler özellikle çevik yazılım geliştirme (*agile development*) ve uyarlanabilir yazılım metodolojilerinde temel felsefe olarak benimsenmiştir.

## S-O-L-I-D Kısaltması
SOLID ilkeleri şunlardır:
* **S** - Tek sorumluluk ilkesi (*Single Responsibility Principle*)
* **O** - Açıklık-kapalılık ilkesi (*Open/Closed Principle*)
* **L** - Liskov'un Yerine Geçme İlkesi (*Liskov Substitution Principle*)
* **I** - Arayüz ayrımı ilkesi (*Interface Segregation Principle*)
* **D** - Bağımlılığın tersine çevrilmesi ilkesi (*Dependency Inversion Principle*)

## SOLID İlkeleri
### Tek sorumluluk ilkesi (Single Responsibility Principle - SRP)

Bir sınıfın değişmesi için yalnızca bir nedeni olmalıdır. Her sınıf veya modül yalnızca tek bir sorumluluğa sahip olmalıdır.

* Tek sorumluluk ilkesine uymayan **sorunlu** **kod örneği:**

*Hem veri kaydeden hem de raporlayan tek bir sınıf.*
```
class Rapor {
    void VeritabaninaKaydet() { /* ... */ }
    void RaporOlustur() { /* ... */ }
}
```


* Tek sorumluluk ilkesini **uygulayan kod örneği:**

*<u>Her sınıfın sadece bir sorumluluğu var.</u>*
```
class RaporOlusturucu {
    void RaporOlustur() { /* ... */ }
}
class RaporKaydedici {
    void VeritabaninaKaydet() { /* ... */ }
}
```


### Açıklık-kapalılık ilkesi (Open/Closed Principle - OCP)

Yazılım varlıkları (arayüzler(soyutlama/interface), sınıflar, modüller, fonksiyonlar vb.) genişletmeye açık, ancak değişikliğe kapalı olmalıdır. Yani mevcut kodu değiştirmek yerine yeni işlevsellik eklemek için kodun genişletilmesi gerekir.


```
abstract class Sekil {
    public abstract double Alan();
}
class Dikdortgen : Sekil {
    public override double Alan() { /* ... */ }
}
class Daire : Sekil {
    public override double Alan() { /* ... */ }
}
```


### Liskov'un yerine geçme ilkesi (Liskov Substitution Principle - LSP)

Alt sınıflardan oluşturulan nesneler, üst sınıfın nesneleri ile yer değiştirdiklerinde aynı davranışı sergilemelidir. Barbara Liskov tarafından 1987'de tanımlanan bu ilke, türetilmiş sınıfların, temel sınıfların yerine sorunsuzca kullanılabilmesini sağlar.

Aşağıdaki örnekte Devekuşu, Kuş yerine geçemediği için LSP ihlal edilmiş olur.

```
class Kus {
    public virtual void Uc() { /* ... */ }
}
class DeveKusu : Kus {
    public override void Uc() { throw new Exception("Deve kuşu uçamaz!"); }
}
```


### Arayüz ayrımı ilkesi (Interface Segregation Principle - ISP)

İstemciler, kullanmadığı arayüzlere(interface) bağımlı olmamalıdır veya bağımlı olmaya zorlanmamalıdır. Büyük ve genel arayüzler yerine, daha küçük ve özelleşmiş arayüzler oluşturulmalıdır.


```
interface IYazici {
    void Yazdir();
}
interface ITarayici {
    void Tara();
}
class CokFonksiyonluYazici : IYazici, ITarayici { /* ... */ }
class BasitYazici : IYazici { /* ... */ }
```


### Bağımlılıkların tersine çevrilmesi ilkesi (Dependency Inversion Principle - DIP)

Bu ilke temel olarak 2 ilkeye dayanır.

1- Üst seviye modüller, alt seviye modüllere bağlı olmamalıdır.

2- Üst seviye modüller arayüzler veya soyutlamalara bağımlı olmalıdır.


```
interface IMesajGonderici {
    void Gonder(string mesaj);
}
class EpostaGonderici : IMesajGonderici {
    public void Gonder(string mesaj) { /* ... */ }
}
class Bildirim {
    private IMesajGonderici gonderici;
    public Bildirim(IMesajGonderici gonderici) { this.gonderici = gonderici; }
    public void Bildir(string mesaj) { gonderici.Gonder(mesaj); }
}
```


## Önemi ve Etkileri
SOLID prensipleri yazılım geliştirme sürecinde aşağıdaki katkıları sağlar:
* Kodun yeniden kullanılabilirliğini artırır
* Sistemin bakımını ve genişletilmesini kolaylaştırır
* Daha test edilebilir ve modüler sistemler sağlar
* Yazılımda esneklik ve ölçeklenebilirliği destekler

## Ayrıca bakınız
* Nesne yönelimli programlama
* Tasarım desenleri (Design Patterns)
* Temiz Kod (Clean Kod)
* GRASP (nesne yönelimli tasarım)
* Kalıtım

## Kaynakça