SOLID yazılım geliştirme

SOLID yazılım, yazılım geliştirme prensiplerinin bir kısaltmasıdır. Bu prensipler, yazılımın daha okunaklı, daha sürdürülebilir ve daha esnek olmasını sağlar. İşte SOLID yazılım hakkında temel 5 başlık:
1.Single Responsibility Principle (SRP) – Tek Sorumluluk Prensibi: Bu prensibe göre, bir sınıfın sadece bir sorumluluğu olmalıdır. Bir sınıfın yapabileceği farklı işlemleri ayrı sınıflara bölmek, kodun daha kolay anlaşılmasına ve bakımının daha kolay olmasına yardımcı olur.

Single Responsibility Principle (SRP) – Tek Sorumluluk Prensibi, bir sınıfın sadece bir sorumluluğu olması gerektiğini savunan bir prensiptir. Yani, bir sınıfın yalnızca bir işi yapması ve o işi en iyi şekilde yapması gerektiği anlamına gelir.
Bu prensip, yazılım geliştirme sürecinde kodun daha okunaklı, daha anlaşılır ve daha sürdürülebilir olmasını sağlar. Ayrıca, bir sınıfın sorumluluklarını ayrı sınıflara bölmek, kodun daha kolay test edilmesine ve bakımının daha kolay olmasına da yardımcı olur.
Örneğin, bir müşteri sınıfı, müşteri bilgilerinin alınması, kaydedilmesi, güncellenmesi ve silinmesi gibi birçok sorumluluğu üstlenebilir. Ancak, bu sınıfın sadece müşteri bilgilerini kaydetmesi sorumluluğunu üstlenmesi daha uygun olur. Müşteri bilgilerini güncelleme, silme ve almayla ilgili sorumluluklar, ayrı sınıflara ayrılabilir.
SRP, kodun daha az bağımlılık yaratmasını ve daha az bağımlılık, kodun daha az hataya neden olması anlamına gelir. Bu prensibe uyulduğunda, kodun daha kolay okunması, anlaşılması ve değiştirilmesi mümkün olur.

2.Open-Closed Principle (OCP) – Açık/Kapalı Prensibi: Bu prensibe göre, bir sınıfın değiştirilebilir olması ancak değiştirilmesine gerek kalmadan genişletilebilir olması gerektiği anlamına gelir. Bu prensip, kodun daha az değiştirilmesi gerektiğinde, daha az hata yapılması ve daha az test edilmesi anlamına gelir.

Open-Closed Principle (OCP) – Açık/Kapalı Prensibi, bir sınıfın değiştirilebilir olması ancak değiştirilmesine gerek kalmadan genişletilebilir olması gerektiğini savunan bir prensiptir. Bu prensibe göre, bir sınıfın davranışı, değiştirilmesi gereken kodlara dokunulmadan, yeni davranışlar eklenerek genişletilebilir olmalıdır.
Bu prensip, yazılım geliştirme sürecinde kodun daha az değiştirilmesi gerektiğinde, daha az hata yapılması ve daha az test edilmesi anlamına gelir. Kodda yapılan herhangi bir değişiklik, diğer kod parçalarını da etkileyebilir ve olası bir hata kaynağı oluşturabilir.
Örneğin, bir şekil sınıfı oluşturduk ve şekillerin alanını hesaplamak için bir metot ekledik. Ancak, sonrasında yeni şekiller eklenmesi gerektiğinde, bu sınıfın değiştirilmesi gerekir. Bu durum, açık/kapalı prensibine uymadığını gösterir.
Bunun yerine, şekil sınıfı, şekil sınıfının genişletilmesi için arayüzler kullanarak değişiklikler yapılmadan genişletilebilir hale getirilebilir. Örneğin, bir dikdörtgen ve daire sınıfı, şekil arayüzünü uygulayarak oluşturulabilir. Böylece, şekil sınıfı değiştirilmeden, yeni şekiller eklenebilir.
OCP, yazılım geliştirme sürecinde kodun daha esnek hale getirilmesine yardımcı olur. Kod, değişikliklere daha dirençli hale gelir ve yeni özellikler eklemek daha kolay hale gelir. Ayrıca, açık/kapalı prensibine uygun kodlar, daha iyi test edilebilir ve daha az hataya neden olur.

3.Liskov Substitution Principle (LSP) – Liskov Yerine Geçme Prensibi: Bu prensip, bir alt sınıfın, üst sınıfın yerine geçebilmesi gerektiği anlamına gelir. Bu, alt sınıfların, üst sınıfların davranışlarını değiştirmediği sürece, üst sınıfların yerine geçebilmesi anlamına gelir.

Liskov Yerine Koyma Prensibi, bir sınıfın türetilen sınıflar tarafından yerine konulabilmesi gerektiğini savunan bir prensiptir. Yani, bir ana sınıfın herhangi bir türetilmiş sınıfı, ana sınıfın kullandığı tüm metotları ve özellikleri aynı şekilde kullanabilmelidir.
Bu prensip, yazılım geliştirme sürecinde kodun daha az hatalı olmasını ve daha az bağımlılık yaratmasını sağlar. Ayrıca, LSP uygunluğu olan kodlar, daha kolay test edilebilir ve bakımı daha kolaydır.
Örneğin, bir hayvan sınıfı oluşturduk ve bu sınıfın türetilen kedi ve köpek sınıfları var. Hayvan sınıfında bir “beslen” metodu var ve kedi/köpek sınıfları da bu metodu kullanabilir. Ancak, kedi sınıfına bir “uç” metodu eklemek, LSP’ye uymaz, çünkü hayvan sınıfında bu metot yoktur ve kedinin uçma yeteneği olmadığı bilinir.
Bunun yerine, hayvan sınıfının, türetilen sınıflar tarafından uygulanabilecek yöntemleri ve özellikleri içermesi gerekir. Bu, türetilen sınıfların ana sınıfın metotlarını ve özelliklerini uygularken, ana sınıfın davranışlarını etkilemeyeceği anlamına gelir.
LSP, kodun daha az bağımlılık yaratmasını ve daha esnek hale getirilmesini sağlar. Kodda yapılan değişikliklerin, diğer kod parçalarını etkilemesi olasılığını azaltır ve yazılımın daha iyi test edilmesini sağlar. Ayrıca, LSP uygunluğuna sahip kodlar, daha kolay anlaşılabilir ve bakımı daha kolaydır.

4.Interface Segregation Principle (ISP) – Arayüz Ayrımı Prensibi: Bu prensibe göre, bir arayüz, sadece kullanıldığı amaçlar için gereksinimleri karşılamalıdır. Bir arayüz, kullanılmayan fonksiyonları içerirse, kodun daha zor anlaşılmasına ve bakımının daha zor olmasına neden olabilir.

ISP, bir sınıfın gereksiz veya kullanılmayan metotları içermemesi gerektiğini savunur. Bu prensip, bir arayüzün, sadece onu uygulayan sınıflar için gereksinim duyulan metotları içermesi gerektiğini vurgular.
ISP prensibi, bir sınıfın, sadece ona ait olan metotları içermesi gerektiğini söyler. Bu prensip, yazılımın daha esnek ve ölçeklenebilir olmasını sağlar. ISP’ye göre, bir arayüz, onu uygulayan sınıfların gereksinimleri doğrultusunda tasarlanmalıdır. Bu, gereksinimleri karşılamayan veya kullanılmayan metotların yer almaması anlamına gelir.
Örneğin, bir müzik çalar sınıfı düşünelim. Bu sınıf, müzik çalmak, duraklatmak, ileri ve geri sarmak gibi temel işlevleri içerir. Ancak, bu sınıf aynı zamanda müzik dosyalarını sıkıştırma veya deşifre etme işlevlerine sahip olmamalıdır. Bu işlevler, müzik çalar sınıfı için gereksizdir ve burada Interface Segregation Principle devreye girer. Bu prensibe göre, müzik çalar sınıfı sadece temel işlevleri içermeli ve sıkıştırma/deşifre etme işlevleri için başka bir sınıf kullanılmalıdır.
ISP prensibi, yazılımın daha az bağımlılık ve daha az karmaşıklık içermesini sağlar. Bu prensip sayesinde, yazılım geliştiricileri, gereksinimleri karşılamayan metotları veya işlevleri kaldırarak yazılımın boyutunu ve karmaşıklığını azaltabilirler. Ayrıca, yazılımın esnekliğini ve ölçeklenebilirliğini artırmak için arayüzlerin doğru tasarlanması önemlidir.
Sonuç olarak, Interface Segregation Principle (ISP), yazılım geliştirme sürecinde SOLID prensiplerinden biridir ve yazılımın daha esnek ve ölçeklenebilir olmasını sağlar. Bu prensip, gereksinimleri karşılamayan veya kullanılmayan metotların yer almamasını ve arayüzlerin sadece onu uygulayan sınıflar için gereksinim duyulan metotları içermesini vurgular. ISP prensibi, yazılımın boyutunu ve karmaşıklığını azaltır ve yazılımın esnekliğini ve ölçeklenebilirliğini artırır.

5.Dependency Inversion Principle (DIP) – Bağımlılık Tersine Çevirme Prensibi: Bu prensip, bir sınıfın başka bir sınıfa bağımlı olmaması gerektiği anlamına gelir. Bu prensip, bağımlılıkların tersine çevrilmesiyle, kodun daha esnek ve sürdürülebilir hale getirilmesine yardımcı olur.

DIP, yüksek seviyeli sınıfların düşük seviyeli sınıflara bağımlı olmaması, ancak aralarındaki bağımlılıkların soyutlama aracılığıyla gerçekleştirilmesi gerektiğini savunur. Bu prensip, yazılımın daha az bağımlı ve daha esnek olmasını sağlar.DIP prensibi, iki ana prensibe dayanır. İlk olarak, yüksek seviyeli sınıflar, düşük seviyeli sınıflara doğrudan bağımlı olmamalıdır. Bunun yerine, aralarında soyutlama aracılığıyla bir arayüz olmalıdır. İkinci olarak, soyutlamalar, uygulamaların tanımlayacağı ve yüksek seviyeli sınıfların kullanacağı arayüzler olmalıdır.Bu prensibi bir örnekle açıklayalım. Bir ödeme işlemi sistemi tasarlanıyor diyelim. Bu sistemi oluşturan iki sınıfımız var: “Ödeme” ve “Banka”. “Ödeme” sınıfı, müşterinin ödeme yapmasını sağlar ve “Banka” sınıfı, ödeme işlemini gerçekleştirmek için gerekli verileri sağlar.Geleneksel bir yaklaşım, “Ödeme” sınıfının doğrudan “Banka” sınıfına bağımlı olmasıdır. Bu, iki sınıf arasında doğrudan bir bağlantı olduğu anlamına gelir ve bir sınıfın değiştirilmesi veya güncellenmesi diğer sınıfı etkileyebilir.DIP prensibine göre, bu bağımlılık soyutlama aracılığıyla gerçekleştirilmelidir. Bu durumda, “Ödeme” sınıfı, “IBanka” arayüzünü kullanarak “Banka” sınıfıyla iletişim kurmalıdır. Bu arayüz, “Banka” sınıfı için tanımlanacak bir arayüzdür. Bu sayede, “Ödeme” sınıfı, “Banka” sınıfı yerine farklı bir sınıf kullanıldığında etkilenmeyecektir.