S.O.L.I.D.

Oğuzhan Delibaş
5 min readMar 10, 2023

--

Bu başlığın detaylarına inebilmek için sizleri bundan çeyrek asır kadar öncesine götürmek istiyorum. O dönemde yazılım mimarisi alanındaki çalışmalarıyla bilinen Robert C. Martin (a.k.a Uncle Bob) ağabeyimiz yazılım mühendisliğinin beş temel prensibi olarak bilinen SOLID prensiplerini tanıtmıştır.

Robert Cecil Martin (Uncle Bob)
Robert Cecil Martin (Uncle Bob)

Temelinde yazılım kalitesinin artırılmasını hedefleyen bu prensipler ilk olarak “Software Rot” üzerine yazılmış 2000 tarihli “Design Principle and Design Patterns” makalesinde duyurulmuştur.

Nedir bu S.O.L.I.D?

Temelinde geliştirilen yazılımın sürecinin yönetilmesini, ilerleyen süreçte bakımının yapılmasını ve hatta değiştirilmesi gibi süreçlerde karşılaşılan zorlukları azaltmak ve yazılımın daha sürdürülebilir hale gelmesini sağlamak amacıyla ortaya çıkmıştır.

Detaylıca inceleyecek olursak:

1- SINGLE RESPONSIBILITY PRINCIPLE (SRP):

Her sınıfın ve metodun tek bir sorumluluğu olmalıdır. Bu sayede sınıf ve metotlar daha az karmaşık hale gelir ve daha kolay anlaşılır.

Örneğin bir oyun geliştiricisi olduğunuzu düşünelim ve geliştrimekte olduğunuz oyununuzda karakteriniz için bir sınıf oluşturduğunuzu varsayalım.
Bu karakter sınıfınız sadece karakterinize ait özellikleri, karakterinizin hareketlerini, etkileşimlerini içermelidir. Hatta duruma göre bunları da ayrıştırmanızda fayda olabileceğini göz önünde bulundurabilirsiniz.

Yazmış olacağınız bu kod sayesinde sınıfınızın yalnızca bir ana hedefi ve sorumluluğu olacak ve bu sayede sınıfınızın içerisinde bulunan kodlar daha anlaşılır, okunaklı ve bakımı kolay olacaktır. Diğer yandan sınıfınızın yeniden kullanılabilirliğinin de artacağı kaçınılmaz bir gerçektir.

2- OPEN / CLOSED PRINCIPLE (OCP):

Bu prensibe göre yazılım bileşenleri, değişime kapalı ve genişletmeye açık olmalıdır. Bu sayede geliştirilen yazılım değişikliklere karşı daha dirençli hale gelir. Kısaca OCP’ye göre bir sınıfın mevcut kodunu değiştirmeden yeni özellikler eklenmelidir.

Örneğin bir Shooter oyun geliştirdiğinizi düşünün. Bu prensibi takip edebilmeniz için öncelikle bir “Silah” sınıfı oluşturmanız gerekecektir.
Bu sınıfın içerisinde ihtiyacınıza göre silah için gereken özellikleri belirleyebilrisiniz. Bu özelliklere örnek olarak “Hasar, Menzil, Ateş Hızı” verilebilir.

Ardından oyununuza eklemek istediğiniz diğer silah tiplerinin sınıflarını oluşturup (örneğin; “Pistol, Shotgun”) daha sonrasında her silah tipinizi bu “Silah” sınıfından miras alacak şekilde ayarlamalısınız. Yeni bir Pistol ya da Shotgun sınıfı oluşturarak her bir silaha ihtiyaç duyduğunuz özellikleri girerek oyununuzdaki çeşitliliği artırabilirsiniz. Bu şekilde, yeni silahlar eklenirken, mevcut kodda herhangi bir değişiklik yapılmadan yeni silahların özellikleri ayarlanabilir.

3- LISKOV SUBSTITUTION PRINCIPLE (LSP):

Bu prensibimizin temel amacı, bir nesne ya da sınıf, türetildiği temel sınıfın davranışlarını bozmadan, aynı şekilde kullanılabilir olmalıdır.

Liskov Substitution prensibi özellikle çoklu miras alımı gibi durumlarda, sınıflar arasındaki doğru ilişkiyi kurmak için önemlidir. Bu prensibin uygulanması, kodun daha sürdürülebilir, esnek ve genişletilebilir olmasına yardımcı olur.

Temel kullanım amacına: “Üst sınıfın veya alt sınıfının herhangi bir hata olmadan aynı şekilde kullanılabilmesi için tutarlılığı sağlamaktır.” diyebiliriz.

picture by. Ugonna Thelma

4- INTERFACE SEGREGATION PRINCIPLE (ISP):

En genel tanımıyla bu prensibe göre, bir arayüz, ihtiyaç duyulmayan ya da kullanılmayan işlevsel özellikleri içermemelidir.

Bu prensip, bir arayüzün birden fazla kullanıcısı olabileceğini ve her kullanıcının arayüzün belirli bir bölümüne ihtiyacı olabileceğini varsayar. Bu nedenle, arayüzlerdeki gereksiz özellikler, kullanıcıların işlerini zorlaştırır ve uygulamaların ölçeklendirilmesini ve yeniden kullanılabilirliğini zorlaştırır.

Örneğin geliştirdiğiniz bir oyundaki karakterleriniz için hareket işlevlerini içeren bir arayüz oluşturduğunuzu düşünün. Eğer bu arayüz içerisinde temel işlevler haricinde bazı özel hareketlerin de bulunduğunu düşünürsek, o özellikleri kullanan ya da kullanmayan tüm karakterler bu arayüze sahip olduğu için o özellikleri kendi sınıfı içerisinde kullanmak durumunda kalacaktır. Bu durum da kod tekrarına yol açacaktır.

Bunun yerine, hareket işlevlerini ayrı bir arayüzde, özel hareket işlevlerini ise ayrı bir arayüzde tanımlayarak karakterlerinizin ihtiyacına uygun arayüzleri uygulayabilirsiniz. Bu şekilde, her karakter sadece ihtiyacı olan arayüzü uygular ve gereksiz özelliklerden arındırılmış bir arayüz tasarımı elde edilir. Bu, karakterlerin kod tekrarını azaltır, uygulamanın daha esnek hale gelmesini sağlar ve yeni özelliklerin eklenmesini kolaylaştırır.

4- DEPENDENCY INVERSION PRINCIPLE (DIP):

picture by. Ugonna Thelma

Bu prensip yüksek seviyeli modüllerin düşük seviyeli modüllere doğrudan bağımlı olmamasını, bunun yerine soyutlamalar üzerinden bağımlı olmalarını sağlayan bir prensiptir.

Örneğin, bir oyun geliştirme projemizde, oyuncuların birbirleriyle ve oyun dünyasıyla etkileşime girmesi gereken bir mekanik olsun. Bu mekanik, düşük seviyeli modüllerin (örneğin ağ iletişimi ve veritabanı işlemleri) kullanılmasını gerektirir.

Dependency Inversion Prensibine göre, yüksek seviyeli modüller (örneğin oyuncu etkileşimi) düşük seviyeli modüllere (örneğin ağ iletişimi ve veritabanı işlemleri) doğrudan bağımlı olmamalıdır. Bunun yerine, yüksek seviyeli modüller, soyutlamalar (örneğin bir veri arayüzü veya bir servis arayüzü) üzerinden düşük seviyeli modüllere bağımlı olmalıdır.

Bu sayede, düşük seviyeli modüllerin değişmesi durumunda yüksek seviyeli modüllerin etkilenmemesi sağlanır. Ayrıca, düşük seviyeli modüllerin farklı türde bir veri kaynağına veya servis arayüzüne bağlanması durumunda, yüksek seviyeli modüllerin değiştirilmesine gerek kalmadan, sadece soyutlamaların güncellenmesi yeterli olur.

Sonuç olarak, Dependency Inversion Prensibi, modüller arasındaki bağımlılıkları soyutlamalar üzerinden oluşturarak, kodun daha esnek, sürdürülebilir ve değişime açık olmasını sağlar.

ÖZET

Kısaca SOLID prensipleri için, yazılım tasarımının temel prensiplerini oluşturur ve yazılımın daha esnek, sürdürülebilir, değişime açık ve kolayca genişletilebilir olmasını sağlar, diyebiliriz.

Bu prensiplere uyarak yazılmış yazılımlar, hataların daha kolay tespit edilmesine, bakım ve geliştirme işlemlerinin daha kolay yapılmasına, yazılımın daha güvenli hale gelmesine ve daha az hata oluşmasına olanak sağlar. Bu nedenle, yazılım tasarımı ve geliştirme süreçleri için oldukça önemli bir rol oynarlar.

Umarım bu yazım sizler için faydalı olmuştur. Yine yazılım camiası üzerine yazmış olduğum diğer yazılarımı da incelemeyi ve kafanıza takılan bir durumda benimle iletişime geçebileceğinizi unutmayın.

Görüşmek üzere.

--

--

Oğuzhan Delibaş

selam, bu sayfada araştırma yaparken karşılaştığım bazı bilgiler var. Okuyacağın bilgiler birçok süzgeçten geçiyor olsa da kesinlik içermemektedir. Teşekkürler!