Merhaba, OOP - Abstraction konusunu tekrar okuyun. Bunun dışında her zaman şöyle düşünün sınıflar düşük seviye modüllerdir, bizim yazdığımı programdaki yüksek seviye modüller düşük seviye modüllerle uğraşmamalıdır.
Şöyle düşün, elinde devre elemanları, kablolar, enerji kaynağı, verici vb. elemanları olan bir elektronik devre var. Bu elektronik devrede istenen sinyali verici üzerinden iletebilmen için farklı şekillerde devreleri tamamlaman gerekiyor, çeşitli switchler yardımıyla istenen sinyali oluşturabiliyorsun. Bu düşük seviye bir modüldür yani bu bir sınıftır.
Bu bilgiler seni ilgilendirmiyor, sen bir insansın, yüksek seviyede bir modülsün.
Bu yüzden devreyle, kabloyla, hangi hattan hangi sinyal çıkacak hesabıyla uğraşmıyorsun. "Televizyon komutası" interfaceini kullanıyorsun. Interface mantığı basitçe budur, bunu unutma.
SOLID prensipleri örneklerini incelemeye devam edersen interface kullanmanın ne kadar iyi bir şey olduğunu daha iyi anlarsın. Zamanla olur. Küçük projelerde önemsiz, koysam da olur koymasam da olur dediğin abstraction eğer proje büyürse önemini daha iyi hissettirir.
Bir iki basit örnek yazacağım birilerine faydası olur umarım.
Aşçı diye bir sınıfın var diyelim. İki tane tarif var, biri kıymalı spagetti, diğeri tavuklu penne. Bunların malzeme bilgilerini, makarnaların pişme sürelerini, makarnanın pişince üzerine domates sosu mu koyulacak, kaşar mı rendelenecek vs bilgilerini aşçı biliyor. if sipariş = kıymalı spagetti ise ilk tarife göre output veriyor, if sipariş = tavuklu penne ise diğer tarifi output veriyor.
Bu yanlış. Diyelim ki menüye yeni yeni tarifler eklendi, lazanya, penne arabiata vs. eklendi, senin her yeni tarif için aşçı sınıfını güncellemen gerekiyor. (SOLID'in O prensibi)
Onun yerine abstraction kullanırsan, abstract bir makarna sınıfı yaratır, makarnanın tüm pişirme kurallarını da alt sınıflara (tavuklu penne sınıfının içinde olacak yani) aktarırsan, aşçı sınıfı ne makarna istenirse istensin "makarna.pişir()" gibi bir method ile output verir. Yoksa aşçı sınıfını if sipariş = şu else if sipariş = bu diye güncellemeye devam edersin her yeni tarifte. Aşçı sadece makarna abstract sınıfını bilirse bu sorun yaşanmaz.
İkinci örnek de şöyle olabilir, bir restoranda yönetici var. Görevi de çalışanların çalışmasını sağlamak. Yani restoran execute olduğu zaman bu yönetici tek tek çalışanların görevlerini tetiklemek durumunda, garsonlara git sipariş al, aşçılara git yemek pişir, kasiyere git fiş kes vb. tek tek görevlerini yaptırtmak durumunda kalır. Yönetici sınıfının içinde her bir garson için garson.siparişAl() garson.siparişiAşçıyaIlet() garson.siparişiMasayaGotur() temizlikçi.yerleriSil() aşçı.yemekPişir() aşçı.eksikMalzemeVarsaTeminEt()... diye sayısız görevi çalıştırmak zorunda kalır. Bu da yanlış bir şey, restoran yöneticisi sınıf üst seviye bir modüldür, bu işlemler ise alt seviye modüllerdir, onlar alt sınıfların sorumluluğunda olmalıdır, alt sınıfların detaylı sorumlulukların tamamını yönetici sınıfında tutmak, if calisan=garson o zaman şunu yapsın else if calisan=barmen o zaman bunu yapsın demek de clean code a aykırıdır.
Onun yerine sorumlulukları alt sınıflara taşırsan, yani garson, alçı vb. kendi sorumluluklarını bilirse; restoranCalisanlari diye bir interface yarattın diyelim, tüm aşçı, garson vb. de bu interface i implemente eden sınıflar olsun, yönetici sınıfı sadece tanımlanmış olan restoranCalisanlari için restoranCalisani.isiniYapKardesim() methodu ile restoranı execute edebilir. Sipariş nasıl alınır, soğan nasıl kavrulur gibi onun için gereksiz olan bilgilere erişmek durumunda kalmaz. Bu da SOLID'in D kuralı.
Bu tür gerçek yaşama da uyarlanabilecek örnekler üzerinden konuyu çalışmaya devam edersen daha iyi anlayacağını, faydaları daha iyi benimseyeceğini düşünüyorum. Abstraction önemlidir, static utility sınıfları hariç hemen her yerde abstraction kullanılmalıdır.