Mustafa Kürşad Başer
Mustafa Kürşad Başer

S-O-L-I-D Prensipleri Nedir?

SOLID Principles, by Mustafa K. Başer

SOLID Prensipleri


Yazılımın hayat döngüsünde sıklıkla karşılaşılan temel sorunlar vardır, bunlar; Esnemezlik, Kırılganlık, Sabitlik, Maliyet. Bu sorunların her biri için çeşitli yaklaşımlar ve çözümler ortaya koyulmuş ve bu yaklaşımların bazıları standartlaşarak günümüzde sıklıkla kullanılan Tasarım Kalıpları (Design Patterns) ve Prensipleri oluşturmuştur.

SOLID Prensipleri de, diğer prensipler gibi kabul görerek standartlaşmış 5 prensibin birleşimiş halidir. Tahmin edebileceğiniz gibi 5 prensibin baş harflerini alarak SOLID olarak adlandırışmıştır, bunlara birazdan değineceğim.

Temel olarak SOLID, geliştirilen yazılımın daha esnek, anlaşılabilir, sürdürülebilir/geliştirilebilir ve yeniden kullanılabilir olmasını hedefler. Ayrıca, potansiyel bakım maliyetlerinin en aza indirgenmesi amaçlanır. SOLID Prensiplerine uygun şekilde geliştirilen yazılım projelerinde, yeni özellik eklenmesi veya müşterinin taleplerinin implemente edilmesi kolaylaşır. Yeni özellik eklemek için sistemi baştan tasarlamamak ve kütüphane veya doğrudan teknoloji değişikliğinde daha esnek bir yapı olması amaçlanır.


S-O-L-I-D Açılımı Nedir?

Single Responsibility Principle (Tek Sorumluluk Prensibi)

Open-Closed Principle (Açık-Kapalı Prensibi)

Liskov’s Substitution Principle (Liskov'un Yerine Geçme Prensibi)

Interface Segregation Principle (Arayüz Ayrımı Prensibi)

Dependency Inversion Principle (Bağlılığı Tersine Çevirme Prensibi)


Single Responsibility Principle (Tek Sorumluluk Prensibi) Nedir?

Single Responsibility Principle yani Tek Sorumluluk Prensibi, SOLID prensipleri arasında yer alan bir prensiptir. Bu prensibe göre, bir sınıfın yalnızca bir sorumluluğu olmalıdır. Sınıfın sorumluluğu, o sınıfın değişikliklere karşı ne kadar dirençli olduğunu belirler.

Örneğin, bir e-ticaret uygulamasında, bir "Sepet" sınıfı, sadece alışveriş sepetinin özelliklerini ve işlevlerini içermelidir. Sepet sınıfı, sipariş yönetimi veya ödeme işlemleri gibi başka görevleri yerine getirmemelidir. Bu sayede, Sepet sınıfının değişikliklere karşı daha dirençli ve sadece kendi sorumluluğu olan bir işlevi yerine getirdiği için daha güvenilir olur.

Single Responsibility prensibi, kodun daha okunaklı, sürdürülebilir ve test edilebilir olmasına yardımcı olur. Ayrıca, kodun daha az bağımlı ve daha esnek olmasını sağlayarak, değişikliklerin daha kolay ve hızlı bir şekilde yapılmasını da sağlar.


Open-Closed Principle (Açık-Kapalı Prensibi)

Open-Closed Principle (OCP), yazılım tasarımı prensiplerinden biridir ve bir sınıfın veya modülün açık ancak değiştirilemez olması gerektiğini belirtir. Bu prensibe göre, bir sınıfın veya modülün davranışı değişebilir, ancak bu değişiklikler, kodu kullanan diğer sınıfları veya modülleri etkilememelidir. Bu prensip, yazılımın daha esnek, genişletilebilir ve sürdürülebilir hale gelmesine yardımcı olur.

Örneğin, bir uygulamada bir ödeme sistemi varsa ve bu ödeme sistemi bir kredi kartıyla ödeme yapma işlevi içeriyorsa, OCP'ye uygun bir tasarım, kodun, farklı bir ödeme yöntemi eklendiğinde değiştirilmemesini sağlamaktır. Bunun yerine, yeni ödeme yöntemi, mevcut kodu etkilemeden uygulamaya eklenmelidir. Bu, uygulamanın ödeme yöntemlerini genişletmek için daha esnek hale gelmesine ve kodun daha az karmaşık hale gelmesine yardımcı olacaktır.

OCP, yazılımın yeniden kullanılabilirliğini artırır ve kodun daha az bağımlılık yaratan, daha esnek bir yapıya sahip olmasını sağlar. Ancak, OCP'ye uymak, yazılımın tasarımını daha fazla düşünmeyi gerektirebilir ve başlangıçta daha fazla zaman ve çaba gerektirebilir.


Liskov’s Substitution Principle (Liskov'un Yerine Geçme Prensibi)

Liskov'un Yerine Koyma Prensibi (Liskov's Substitution Principle - LSP), yazılım tasarımındaki bir prensiptir. Bu prensibe göre, bir üst sınıfın nesneleri, alt sınıflarının nesneleriyle yer değiştirilebilir olmalıdır. Başka bir deyişle, alt sınıf nesneleri, üst sınıf nesnelerinin yerine geçebilmelidir.

Örneğin, bir Şekil sınıfı düşünelim ve bu sınıfın çeşitli alt sınıfları (Kare, Dikdörtgen, Elips) olsun. LSP'ye uygun bir tasarım, bu alt sınıfların tüm Şekil sınıfının özelliklerini ve davranışlarını koruduğu ve eklediği bir tasarımdır. Yani, Kare sınıfı, Şekil sınıfının yerine kullanılabilmeli ve aynı davranışları gösterebilmelidir. Dikdörtgen sınıfı da aynı şekilde Şekil sınıfının yerine kullanılabilir olmalı ve aynı davranışları gösterebilmelidir.

LSP'nin temel amacı, alt sınıfların, üst sınıflarının yerine geçebildiği bir sistem tasarlamaktır. Bu prensibin amacı, bir üst sınıfın tüm davranışlarını ve özelliklerini koruyarak, alt sınıfların kendi özelliklerini ve davranışlarını eklemesine olanak tanımaktır.

LSP'nin uygulanması, kodun yeniden kullanılabilirliğini ve bakım kolaylığını artırır. Bu prensibe uyulması, yazılımın geliştirilmesinde oluşabilecek hataların ve sorunların önlenmesine de yardımcı olur.


Interface Segregation Principle (Arayüz Ayrımı Prensibi)

Interface Segregation Principle (ISP), yazılım tasarımındaki beş SOLID prensibinden biridir ve arayüzlerin doğru bir şekilde ayrıştırılmasını vurgular. Bu prensibe göre, bir arayüz mümkün olduğunca özelleştirilmiş olmalıdır, böylece onu kullanan sınıflar sadece ihtiyaçları olan özellikleri kullanabilirler.

Bir örnekle açıklamak gerekirse, düşünelim ki bir otel rezervasyon sistemi yazıyoruz. Bu sistemi kullanacak olan müşteriler, otel odalarını arayabilecekleri ve rezervasyon yapabilecekleri bir arayüzle etkileşime girecekler. Ancak, bu arayüz, müşterilerin sadece rezervasyon yapabilmeleri için ihtiyaç duydukları özellikleri içermelidir. Örneğin, müşterilerin otel odalarının ne kadar süreyle rezerve edilebileceğini veya hangi ödeme yöntemlerinin kabul edildiğini bilmelerine gerek yoktur. Bu gereksiz bilgiler, müşterilerin kafasını karıştırabilir ve arayüzün karmaşık görünmesine neden olabilir.

Bunun yerine, arayüz sadece müşterilerin ihtiyaç duydukları bilgileri içermeli ve fazla detaya girmeden yalın olmalıdır. Ayrıca, müşterilerin ihtiyaçlarına göre arayüzün farklı versiyonları olabilir. Örneğin, bir müşteri otel odasını telefonla rezerve etmek isteyebilirken, bir diğeri internet üzerinden rezervasyon yapmak isteyebilir. Bu durumda, arayüz, farklı rezervasyon yöntemleri için ayrı ayrı tasarlanabilir.

ISP, yazılımın esnek ve genişletilebilir olmasını sağlar. Sınıfların ihtiyaç duymadığı özelliklerden arındırılmış arayüzler, yazılımın bakımı ve değiştirilmesi daha kolay hale getirir. Bu sayede, yeni özelliklerin eklenmesi veya mevcut özelliklerin değiştirilmesi daha az riskli olur.


Dependency Inversion Principle (Bağlılığı Tersine Çevirme Prensibi)

Dependency Inversion Principle (Bağımlılıkların Tersine Çevrilmesi Prensibi), SOLID prensiplerinin beşincisi ve sonuncusudur. Bu prensip, kodun esnekliğini ve yeniden kullanılabilirliğini artırmak için tasarlanmıştır.

Bağımlılıkların Tersine Çevrilmesi Prensibi, yüksek seviyeli modüllerin düşük seviyeli modüllere bağımlı olmamasını, ancak her iki seviyenin de soyutlamalara bağımlı olması gerektiğini savunur. Yani, soyutlamalar (interfaceler, soyut sınıflar vb.) düşük seviyeli detayları gizlemelidir, bu sayede yüksek seviyeli modüller düşük seviyeli modüllerin iç yapısını bilmek zorunda kalmaz.

Bu prensip, aynı zamanda "yüksek seviyeli modüller düşük seviyeli modüllere karşı bağımlı olmamalıdır; bunun yerine her ikisi de soyutlamalara bağımlı olmalıdır" şeklinde de ifade edilebilir.

Örneğin, bir uygulamanın veritabanı işlemleri gerçekleştiren bir modülü varsa ve bu modül doğrudan bir veritabanı bağlantısı kullanıyorsa, bu bağlantının değiştirilmesi durumunda tüm modülün yeniden yazılması gerekebilir. Ancak, bu prensibe uygun olarak, veritabanı bağlantısı soyutlamalar aracılığıyla (örneğin bir interface) kullanılırsa, bağlantıyı değiştirmek istendiğinde sadece soyutlamaların değiştirilmesi yeterli olacaktır ve tüm modülün yeniden yazılması gerekmez.

Bu prensip sayesinde, modüller birbirine sıkı sıkıya bağlı olmaktan ziyade birbirleriyle esnek bir şekilde etkileşim kurarlar. Bu da, kodun bakımını ve genişletilmesini daha kolay hale getirir.


Sonuç

Bu makalede, SOLID prensiplerinin her birinin ne olduğunu, neden önemli olduğunu ve uygulanması için nasıl bir yaklaşım benimsenmesi gerektiğini açıklamaya çalıştım. Bu prensipler, yazılım geliştirme sürecindeki sorunları en aza indirerek, daha okunaklı, sürdürülebilir ve esnek kodlar yazmamızı sağlar.

Single Responsibility Prensibi, her sınıfın sadece bir sorumluluğu olması gerektiğini vurgular. Open-Closed Prensibi, yazılımın yeni gereksinimleri karşılamak için açık ancak değişmez olması gerektiğini savunur. Liskov Substitution Prensibi, türetilen sınıfların ana sınıfın yerine kullanılabileceği bir hiyerarşi oluşturmanızı sağlar. Interface Segregation Prensibi, mümkün olan en az sayıda bağımlılık oluşturmak için arayüzlerin ayrı ayrı tanımlanması gerektiğini belirtir. Son olarak, Dependency Inversion Prensibi, düşük seviyeli modüllerin yüksek seviyeli modüllere bağımlı olmamasını ve istemci kodunun detaylarını bilmemesini sağlar.

Bu prensipleri anlamak ve uygulamak, yazılım geliştirme sürecindeki kalite, esneklik ve sürdürülebilirlik gibi temel konuları ele almak açısından son derece önemlidir. Yazılım geliştiricileri olarak, bu prensipleri anlamaya ve uygulamaya odaklanarak daha iyi yazılım kodları yazabilir, uzun vadeli projelerde başarılı olabilir ve müşterilerimizin ihtiyaçlarını en iyi şekilde karşılayabiliriz.

Serinin devamına aşağıdan erişebilirsiniz. Ayrıca, tüm yazılarıma buradan ulaşabilirsiniz. Şimdilik hoşça kalın!

  • Mustafa Kürşad Başer
    Mustafa Kürşad BAŞER

    Yazılım Mühendisi. Okumaktan, yazmaktan; öğrendiğini paylaşmaktan büyük keyif duyar. Yazılım geliştirme dışında; tarih, sanat ve insan psikolojisine dair okuma yapmak en rafine tutkularından.