KategorilerJava Programlama

5 Temel S.O.L.I.D. Prensibi

S.O.L.I.D. prensipleri, yazılım geliştirmenin temel taşlarından biri olarak kabul edilir ve bu kavram, Patika.dev ve n11 firmalarının iş birliğiyle hayata geçirilen n11 TalentHub Backend Bootcamp programında asistan olarak görev aldığım bu heyecan verici yolculuğun da merkezinde yer alıyor.

Bu önemli rolde, yazılım eğitmenine ve diğer asistan arkadaşlara destek olma sorumluluğunu üstlenerek öğrencilere rehberlik ediyorum. Kişisel ve profesyonel gelişimime katkıda bulunmak amacıyla, eğitim sürecinde öğrendiklerimi sistematik bir şekilde kayıt altına alıyorum ve bu doğrultuda “n11 TalentHub Backend Bootcamp Notlarım” adlı bir liste oluşturdum. Her eğitim günündeki kazanımlarımı bu listede dikkatle not alarak, hem kendim için hem de bu alanda bilgi arayanlar için bir kaynak oluşturmayı hedefliyorum. Bu bilgi birikimimi daha geniş bir kitle ile paylaşmak için yazdığım blog yazılarımın ilkinin konusu, yazılımın vazgeçilmez unsurlarından S.O.L.I.D. prensipleri üzerine olacak.

Yazılım geliştirmede hayati bir rol üstlenen S.O.L.I.D. prensipleri, kod kalitesini ve geliştirme süreçlerinin etkinliğini artırmada kilit öneme sahiptir.

Bu prensipler; Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation ve Dependency Inversion olmak üzere beş temel ilkeyi içerir. Her biri, yazılımınızın daha robust (sağlam), bakımı kolay ve modüler olmasını sağlayarak, uzun vadede yazılımınızın adaptasyonunu ve genişletilmesini kolaylaştırır.

S.O.L.I.D. Prensipleri
S.O.L.I.D. Prensipleri


S.O.L.I.D. prensipleri, yazılım mühendisliği ve nesne yönelimli programlama alanlarında, daha temiz, anlaşılır ve sürdürülebilir kod geliştirmek için oluşturulmuş bir dizi kılavuz prensiptir.

Her bir prensip, kodun belirli bir yönünü iyileştirmeye odaklanır ve birlikte, karmaşık yazılım sistemlerinin tasarım ve bakımını kolaylaştıran güçlü bir yapı oluştururlar. İşte bu prensipler ve daha ayrıntılı açıklamaları:

  • Tek Sorumluluk Prensibi (Single Responsibility Principle – SRP): Bu prensip, bir sınıfın yalnızca tek bir işlevsellikten veya sorumluluktan sorumlu olması gerektiğini belirtir. Bu yaklaşım, kodun okunabilirliğini ve bakımını kolaylaştırır.
  • Açık/Kapalı Prensibi (Open/Closed Principle – OCP): Yazılım varlıklarının (sınıflar, modüller, fonksiyonlar vb.) genişlemeye açık, değişikliğe kapalı olması gerektiğini ifade eder. Bu, mevcut kodun değiştirilmeden, yeni işlevselliklerin eklenmesine izin veren bir tasarımı önerir.
  • Liskov’un Yerine Geçme Prensibi (Liskov Substitution Principle – LSP): Bu prensip, alt sınıfların, üst sınıflarının yerine geçebileceğini belirtir. Yani, bir sınıfın herhangi bir alt sınıfı, üst sınıfın işlevselliğini bozmadan yerine kullanılabilmelidir. Bu, yazılımın modülerliğini artırır ve sınıflar arasındaki bağlantıyı güçlendirir. Java’da, alt sınıfların üst sınıfların fonksiyonlarını doğru bir şekilde uyguladığından emin olmak için bu prensibi takip etmek önemlidir.
  • Arayüz Ayırma Prensibi (Interface Segregation Principle – ISP): Bir sınıfın, kullanmadığı arayüzleri uygulamak zorunda kalmaması gerektiğini belirtir. Bu, “genel amaçlı” arayüzler yerine, daha spesifik ve işlevsel arayüzler kullanılmasını önerir.
  • Bağımlılık Ters Çevirme Prensibi (Dependency Inversion Principle – DIP): Yüksek seviyeli modüllerin düşük seviyeli modüllere doğrudan bağlı olmaması gerektiğini ve her ikisinin de soyutlamalara bağlı olması gerektiğini ifade eder. Bu, modüller arasındaki bağımlılıkları azaltır ve kodun test edilebilirliğini artırır.

S.O.L.I.D. Single Responsibility Principle (SRP)

Örneğin, bir KullaniciYonetimi sınıfım varsa, bu sınıfın yalnızca kullanıcı işlemleri ile ilgili sorumlulukları olmalıdır, loglama veya veritabanı işlemleri gibi başka işlerle uğraşmamalıdır.

public class KullaniciYonetimi {
    public void kullaniciEkle(Kullanici kullanici) {
        // Kullanıcı eklemekle ilgili işlemler
    }

    public void kullaniciSil(int kullaniciId) {
        // Kullanıcı silmekle ilgili işlemler
    }
}

S.O.L.I.D. Open/Closed Principle (OCP)

Örneğin, bir ödeme işlemi sınıfı tasarlıyorsam, farklı ödeme yöntemlerini kolayca ekleyebilmek için bir arayüz tanımlayabilirim.

public interface OdemeYontemi {
    void ode(double tutar);
}

public class KrediKarti implements OdemeYontemi {
    @Override
    public void ode(double tutar) {
        // Kredi kartı ile ödeme işlemleri
    }
}

public class PayPal implements OdemeYontemi {
    @Override
    public void ode(double tutar) {
        // PayPal ile ödeme işlemleri
    }
}

S.O.L.I.D. Liskov Substitution Principle (LSP)

Java’da, bu prensibi sağlamak için, alt sınıfların üst sınıfın sözleşmesine sadık kalmasına dikkat ederim.

public abstract class Arac {
    public abstract void hareketEt();
}

public class Araba extends Arac {
    @Override
    public void hareketEt() {
        // Arabanın hareket etme işlemleri
    }
}

public class Bisiklet extends Arac {
    @Override
    public void hareketEt() {
        // Bisikletin hareket etme işlemleri
    }
}

S.O.L.I.D. Interface Segregation Principle (ISP)

Java’da, işlevselliği temsil eden özelleşmiş arayüzler tanımlayarak bu prensibi uygularım.

public interface Yazdirilabilir {
    void yazdir();
}

public interface Taranabilir {
    void tara();
}

public class FotokopiMakinesi implements Yazdirilabilir, Taranabilir {
    @Override
    public void yazdir() {
        // Yazdırma işlemleri
    }

    @Override
    public void tara() {
        // Tarama işlemleri
    }
}

S.O.L.I.D. Dependency Inversion Principle (DIP)

Java’da, bu prensibi uygulamak için arayüzler ve soyut sınıflar kullanırım. Bu, kodun daha modüler ve test edilebilir olmasını sağlar.

public interface VeritabaniBaglantisi {
    void baglan();
}

public class MySQLVeritabani implements VeritabaniBaglantisi {
    @Override
    public void baglan() {
        // MySQL veritabanına bağlanma işlemleri
    }
}

public class VeritabaniIslemleri {
    private VeritabaniBaglantisi veritabaniBaglantisi;

    public VeritabaniIslemleri(VeritabaniBaglantisi veritabaniBaglantisi) {
        this.veritabaniBaglantisi = veritabaniBaglantisi;
    }

    public void veriEkle() {
        veritabaniBaglantisi.baglan();
        // Veri ekleme işlemleri
    }
}

Bu beş SOLID prensibini projelerimde uygulayarak, kodumun daha anlaşılır, sürdürülebilir ve genişletilebilir olmasını sağlıyorum. Java örnekleri ile bu prensiplerin nasıl hayata geçirilebileceğini göstermek, prensiplerin pratikteki uygulanabilirliğini vurguluyor.

Kaynak: https://en.wikipedia.org/wiki/SOLID

Yayınlayan Tarık KAMAT

Bir yanıt yazın

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