OOP - Object Oriented Programming

Nesneye dayalı programlamada Solid Prensipleri – Object Oriented Solid principles

Rate this post

Modern programlama tekniklerinde olmazsa olmaz olan OOP (object oriented programming) mimarisi , programcıların sadık kalacağı kural ve teknikler ile daha yönetilebilir, genişletilebilir ve stabil kodlar ortaya çıkartilabilir. Uzun yıllar boyunca program geliştiricileri tarafından bir çok deneme yanılma yollar veya planlı tasarımlar sonucunda ortaya çok ciddi bir bilgi ve tecrübe birikimi ortaya çıkmıştır. Bugün bu tecrübeler farklı isimlerle yazılım geliştirme dünyasında kullanılmaktadır. Bunlardan en temel bilineni olan Solid prensibi bir çoğumuz farkında olmadan bile kullanmışızdır aslında. Şayet bilmeden kullandığımız yada bilmeyi isteyeceğimiz bu Solid denen prensibe bir göz atalım.

 

Solid Nedir ?

Solid ismini alt bünyesinde barındırdığı 5 alt prensibten alır. Her prensibin baş harflerden ortaya SOLID çıkmaktadır.

 

1. (S)ingle Responsibility Principle

2. (O)pen/Closed Principle

3. (L)iskov ‘s Substitution Principle

4. (I)nterface Segregation Principle

5. (D)ependency Inversion Principle

Bu Nesneye yönelik programlama metodolojileri ve alt başlıkları inceleyelim.
1-Single Responsibility

Bu prensibi kısaca bir örnekle açıklamak gerekirse , Örneğin bir dosya kopyalama işi yapıyorsunuz ağ üzerinden ve dosyanın adındaki boşlukları silip _ haline getirmek istediniz.

Yani

Kaynak : “\\192.168.1.2\paylasim\19 05 2017 143000.mpg

Hedef :”E:/arsiv/2017/05/19/19_05_2017_143000

Kodunuzu sadece bir void method ile ; Ağ üzerinde dosya var mı ? Evet , varsa boşlukları _ ile değiştir yaptınız, Yıl/Ay/Gun arşiv yapısı içerisinde kopyalama yapılacak arşiv haline getirdiniz. Kopyalama başarılı ise dosyanın ağ üzerindeki kaynak silinmesi işinide yapıyor. Buraya kadar herşey yolunda , peki yöneticiniz size şunları derse ne yapacaksınız ??

Artık ağ üzerindeki hedef silinmeyecek ?

Artık oranın kullandığı arşiv formatı Gun/Ay/Yıl , ama önceden kullandığım formatada destek verilecek !! (eski kodları silmeye izin yok)

Artık Dosya kopyalama yarıda kalmış mı tespit edilecek ?


 

Eğer kodu yine tek void methodda düzenlerdim diyorsanız bu kesinlikle single responsibility prensibine uygun yaklaşım değildir. Ortaya karmakarışık bir business kuralları olan bir kod çıkacak ve if satırları ile dolan , sürekli yukarıda satırlara bağımlı olan yeniden kullanılamaz kodlar oluşur. Bir şekilde çözersiniz evet fakat siz o yazılım şirketinden yada projeden ayrıldığınızda sizi hayırla anmayacak üstad gibi nitelemeler yerine daha sevimsiz nitelemelere  maruz kalabilirisiniz kulağınız duymasa bile.

Çözüm :

1- Arşiv yöntemini string olarak üretecek fonksiyon yazılır, böylece kaç farklı yöntem olursa olsun ortaya bir arşiv format kütüphanesi çıkar. Eski bir formata destek vermek için 50 tane referans alan çağrının içinde kodlar 50 kere kopyalanmaz. (Ölümcül hata)

 

2- Ağ üzerinde silme işlemi yapacak kod dışarıya void olarak çıkarılır.

Böylelikle değişiklik yapılacak noktaları tespit etmek, kod okunurluğunu arttırmak, yazdığınız kodu tekrar kullanılabilir hale getirmek , geriye destek vermek son derece yönetilebilir ve kolay olmaktadır.

2-  Open Closed Principle

Bu prensip proje geliştirirken sınıf ve metodların değişime açık , bu sınıfları  tüketen kodların ise değişime kapalı olmasıdır . Nasıl olduğunu gelin inceleyelim

Sınıfı ve methodu Tüketen Kod , örneğimizde Program.cs içinde düşünelim

Yukarıdakı kodu gelin bir senaryoya dökelim.

 

Yukarıdaki kodda araba ve otobüs satın almak için sepetinize eklediniz, şimdi 2 senaryo daha düşünelim.

1- Araba almaktan vazgeçtiniz ve yerine otobüs alacaksınız?

2- Minibus almak istiyorsunuz , sepete bunu atabilmek istiyorsunuz

 

Çözümü aşağıdaki kodlarda gerçekleştirip açıkladım.

Output :

Otobüs Satın aldınız, hediyeniz 6 lastik

Otobüs Satın aldınız, hediyeniz 6 lastik

Minibüs Satın aldınız, hediyeniz 5 lastik

Sonuç: Yukarıda gördüğünüz üzere sepetteki değişiklerden ana kod ciddi denilebilecek şekilde etkilenmedi. Yeni bir ürün yeni bir sınıf ile sisteme tanıtıldı ve doğrudan sepetin formatına uygun ve bozmayacak ve doğrudan desteklenebilecek şekilde IBuyer sınıfından implemente edildi. Tüketme kısmında kolaylıkla vazgeçilen ürünün yeni tipi, sepetin dinamik haline uygun şekilde türetildi. Sepet kısmımızın bozulmaya değişikliğe uğramadan kapalı kaldığını farkettirebildiysem ne mutlu bana 🙂 , Yani Sepetimiz şöyle oluşturulmadı ;

List<BusBuyer> buycarList = new List<BusBuyer>();

her biri için bu yapılmış olsaydı , her biri için ayrı bir sepet , ayrı bir satış gerçekleştirme döngüsü , uzayıp gidecekti . Sepet toplamlarını toplayıp , en son toplam fiyat diyecektik. İtiraf edelim bu iş hamallık 😉

3-Liskov ‘s Substitution Principle

Bu prensibin genel amacı Implement edilmesi zorunlu olan  metodların türetilen sınıfta kullanılmasının mecburi olması prensibidir. Misal vermek gerekirse ;

Örneğin yönetmelik gereği mecbur olan bir asansörlü bir bina tasarlamanız gerekiyor  , asansörün en boy bilgisini throw new exception() olarak döndüren bir metodun ne demek istediğini anlayabilmek , anlatabilmek için çok çaba gerek 🙂 Bir sınıf, bir sınıftan veya interfaceden türetilmişse ! exception dönen veya boş dönen metod implementasyonları yada override işlemleri olmamalıdır.

Özetle mecbur olmayan şeyleri mecbur gibi dayatmamak  , yeteneğimiz olmayan şeyleri de yeteneğimiz gibi göstermemek lazım.  Eski bir arabada ABS özelliği yokken var göstermeniz gülünç olur 🙂 Var ama çalışmıyor demek sizi gülünçlükten kurtarmaz, Yada eski araçlara saatte 300 km gitme zorunluluğu dayatmak ! Yada villalara otopark dayatmak , ne kadar da benzer yanlışlar.

Aşağıdaki gibi tasarımda exception aldığınızda program kırılır. Gider exception fırlatan satırı silersiniz boş sonuç dönersiniz eyvallah fakat çirkin bir iş yaparsınız bu prensibe göre.

ÇİRKİN TASARIM

DOĞRU TASARIM İSE AŞAĞIDAKİDİR

 

 

GÜZEL VE DOĞRU TASARIM

4-Interface Segregation Principle

Bu prensip Interface arayüzlerinize gerektiğinden fazla method eklenmesinin Liskov ‘s Substitution Principle olduğunda gibi gereksiz ve çirkin bir iş olduğunu söyler. Liskov da abstract sınıf için kural konulurken , burada ise Interface için bu kural koyuluyor. Aşağıdaki tasarım doğru bir tasarımdır. Yanlış tasarım nedir derseniz bana göre ; EnBoy methodunu IAsansorde tanımlayıp, IMecburiAsansor interfacesini silmek denebilir. Özetle mecbur olmayan şeyleri mecbur gibi dayatmamak  , yeteneğimiz olmayan şeyleri de yeteneğimiz gibi göstermemek lazım.  Eski bir arabada ABS özelliği yokken var göstermeniz gülünç olur 🙂 Var ama çalışmıyor demek sizi gülünçlükten kurtarmaz, Yada eski araçlara saatte 300 km gitme zorunluluğu dayatmak ! Yada villalara otopark dayatmak , ne kadar da benzer yanlışlar.

5-Dependency Inversion

Bağımlılıkların terse çevrilmesi olarak çevrilen bu prensipte üst sınıf alt sınıftaki değişikliklerden etkilenmemesi asıl amaçtır. Kısaca bir lokantanız var ve işe çorbacı aldınız. Usta domates verilse çorba yapacak, kara lahana verilse yine çorba yapacak, hatta turp verseniz , hamsi verseniz bile 🙂 onun işi çorba yapmak sorun çıkarmak değil. Bundan çorba olmaz demek onun işi değil , bunu söylemek iş kurallarını tanımlayan patrona kalmış birşeydir. Programlama dünyasında da bu kuralları yazılım mimarları , analizciler, programcılar tasarlar..  Kod örneğimiz ile inşaAllah daha anlaşılır hale getirebilmişimdir.

output:

 

Al sana Kara Lahana
KaraLahana Pişirildi.
Al sana Domates
Domates Pişirildi.

 

DİĞER PRENSİPLER
Kiss Principle : Keep it Simple Stupid
Bir problemi çözerken aşırı gereksiz zorluklara kaçılmamalı, sadece gerekiyorsa zor olan yöntem tercih edilmelidir. Kodun okunaklı anlaşılır olması çok önemlidir
Yangi Principle : You Aren’t Gonna Need It!
Bu prensip en çok neme lazımcıları sevindirecek prensibtir 😀 . Eğer bir özellik kesin bir şekilde lazım değil veya istenmeyecekse bu kurala riayet ediyoruz , başımıza gereksiz bela veya kötü kod,tasarım yükü almıyoruz 😉
Dry Principle : Don’t Repeat Yourself
Bu prensipte ise kendi kodunu tekrar eden arkadaşlara pasta ,tatlı alma cezası verdiğimiz, niçin CTRL+H tuşlarını yıprattığının sorusunu sorduğumuz prensiptir. Single responsibility’e uymamak programcılıkta hamallıktır, sürekli unutmaktır , kesintisiz tekrarlayan buglardır. 50 yerdeki kopya kod 500 kere bug üretebilir ,abarttın demeyin bence.
Reuse-Release Equivalence Principle
Sistemde kullanılan paketler/namespace’ler arasındaki bağımlılıkları yönetmek “tekrar kullanılabilir” yapılar kurmakla mümkün olur.
Common Closure Principle
Ortak Kapama Prensibi, Single Responsibility’nin namespace’ler için uyarlanmış halidir.

 

 

Benzer Yazılar:



This post has been seen 751 times.
Be the First to comment.

Leave a Comment

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir