İnsanlar için sadeleştirilmiş SOLID Prensipleri
SOLID her yerde karşımıza çıkan, mülakatlarda sorulan temel bir konu. SOLID Prensipleri genellikle çok detaylı ve karmaşık yöntemlerle anlatıldığı için ezberleyip ezberleyip unutabiliyoruz. Bu bilinçle, ChatGPT’ye SOLID’i açıklattım. Ezberlemek yerine mantığını kavramak daha doğru olacaktır.
Tek Sorumluluk Prensibi (Single Responsibility Principle — SRP):
Anlatım: Bir sınıfın ya da fonksiyonun sadece bir işi olmalı.
Örnek: Bir oyuncak arabayı düşünelim. Onun işi sadece ileri gitmek. Eğer birden fazla işi olursa, mesela hem gider hem müzik çalarsa, arabayı kontrol etmek zorlaşır. Bu yüzden arabaların sadece gitmesi daha iyi.
// Kötü Örnek
class Araba {
hizlan() {
// ...
this.gucVer();
}
gucVer() {
// ...
}
muzikCal() {
// ...
}
}
// İyi Örnek
class Araba {
hizlan() {
// ...
this.gucVer();
}
gucVer() {
// ...
}
}
class MuzikCalar {
muzikCal() {
// ...
}
}
Açık Kapalı Prensibi (Open/Closed Principle — OCP):
Anlatım: Bir modül, sınıf veya fonksiyon, değişikliklere kapalı, yeni özelliklere açık olmalı.
Örnek: Lego blokları gibi düşünelim. Yeni bir parça ekleyebilirsin, ama mevcut parçaları kırmadan değiştiremezsin.
// Kötü Örnek
class Urun {
constructor(ad, fiyat) {
this.ad = ad;
this.fiyat = fiyat;
}
indirimYap(yuzde) {
this.fiyat = this.fiyat - (this.fiyat * (yuzde / 100));
}
}
// İyi Örnek
class Urun {
constructor(ad, fiyat) {
this.ad = ad;
this.fiyat = fiyat;
}
fiyatHesapla() {
return this.fiyat;
}
}
class IndirimliUrun extends Urun {
constructor(ad, fiyat, indirimYuzdesi) {
super(ad, fiyat);
this.indirimYuzdesi = indirimYuzdesi;
}
fiyatHesapla() {
return super.fiyatHesapla() - (super.fiyatHesapla() * (this.indirimYuzdesi / 100));
}
}
Liskov Yerine Koyma Prensibi (Liskov Substitution Principle — LSP):
Anlatım: Bir üst sınıfın nesnesi, onun alt sınıflarının nesneleri ile yer değiştirebilir olmalıdır.
Örnek: Kuşlar uçabilir, yüzücüler yüzebilir. Eğer “Kuş” sınıfı ile bir şeyler yapabiliyorsak, “Ördek” gibi bir alt sınıfını kullanmalıyız.
// Kötü Örnek
class Kus {
uc() {
// ...
}
}
class Ordek extends Kus {
yuz() {
// ...
}
}
// İyi Örnek
class Kus {
hareketEt() {
// ...
}
}
class Ordek extends Kus {
hareketEt() {
// ...
}
}
Arayüz Ayırma Prensibi (Interface Segregation Principle — ISP):
Anlatım: Bir istemci sadece ihtiyacı olan özelliklere sahip bir arayüz ile ilişki kurmalıdır.
Örnek: Bir çocuk oyuncağı düşün. Sadece gerekli olan düğmeleri görmeli, gereksiz olanları değil.
// Kötü Örnek
class Oyuncak {
cal() {
// ...
}
yavasla() {
// ...
}
}
// İyi Örnek
class MuzikCalabilen {
cal() {
// ...
}
}
class Hizlanabilen {
hizlan() {
// ...
}
}
Bağımlılıkların Tersine Çevrimesi Prensibi (Dependency Inversion Principle — DIP):
Anlatım: Modüller, yüksek seviyeli politikalara bağlı olmalı, ayrıntılar ise düşük seviyeli politikalara bağlı olmalıdır.
Örnek: Araba sürerken, sadece direksiyonu çevirirsin. Motorun içinde neler olduğunu düşünmezsin. Bu yüzden arabada direksiyonun dışında neler olduğu seni etkilemez.
// Kötü Örnek
class Araba {
constructor() {
this.motor = new Motor();
}
}
class Motor {
// ...
}
// İyi Örnek
class Araba {
constructor(motor) {
this.motor = motor;
}
}
class Motor {
// ...
}
const motor = new Motor();
const araba = new Araba(motor);
Bu yazı hazırlanırken büyük ölçüde ChatGPT’den faydalanılmıştır.