BMPortfolio
Back to all articles

Yazılım Geliştirme

SOLID Prensipleri Nedir? C# Örnekleriyle Basit Anlatım

Bu yazıda SOLID prensiplerini sade bir dille ve C# örnekleri üzerinden ele alıyorum. Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation ve Dependency Inversion prensiplerinin ne işe yaradığını ve nasıl uygulanabileceğini örneklerle inceliyoruz

7 views
Cover for SOLID Prensipleri Nedir? C# Örnekleriyle Basit Anlatım

1. SRP – Single Responsibility Principle

Single responsibility Principle şunu söyler: her sınıfın tek bir sorumluluğu olmalıdır. Yani bir class birden fazla farklı işi yapmamalıdır.

Örneğin: UserService sınıfını düşünelim. Eğer ki bu sınıf hem:

·         Kullanıcı kaydediyor

·         Email gönderiyor

·         Dosyaya yazıyor

İse çok fazla işi aynı sınıfa toplamış oluruz. Bu durum SRP’ye aykırı bir durumdur.

OCP – Open/Closed Principle

OCP şunu söyler: kod geliştirmeye açık değiştirmeye kapalı olmalıdır. Buradaki amaç şudur: “Yeni özellik istediğinde mevcut çalışan kodu sürekli değiştirmek zorunda kalmamalıyız.”

Yani yeni bir özellik eklemek istediğim zaman, çalışan eski kodu değiştirmemeliyim

Buradaki “Open” = yeni özellik eklemeye açık anlamına gelirken “Closed” = mevcut kodu değiştirmeye kapalı anlamına gelir.

Örnek:

Diyelim ki bir ödeme sistemimiz var.

Şuanda burada 2 farklı ödeme türü var: CreditCard ve Cash.

Biz buna sonradan PayPal eklemek istediğimizde gidip mevcut PaymentService Sınıfına girip bunu ekleriz

Sonra havale ile ödeme geldiğinde tekrar gider eski sınıfa ekleme yaparız

Yani burada her seferinde PaymentService sınıfını değiştiriyoruz. İşte open/closed buna karşı çıkıyor.

Open/Closed prensibine göre nasıl yapmamız gerekir?

1.       Önce interface oluştururuz

Kredi Kartı eklediğimizde

Nakit geldiğinde

Yani burada sonradan yeni bir özellik geldiğinde gidip yeni sınıf oluşturup yaparız. Bu şekilde de eski kodumuzu değiştirmeyiz

L – Liskov Substition Principle

LSP, ortak bir referanstan türeyen nesnelerin hiçbir şeyi bozulmadan birbirleriyle değiştirilebilmesi gerektiğini yani birbirlerinin yerine geçebilmesi gerektiğini öneren bir prensiptir. Yani hiçbir alt sınıf, uygulamış olduğu base class’ın metotlarını ihlal etmemelidir. Yani hiçbir metot boş kalmamalı veya boş kalmasın diye Not Implemented Exception gibi hatalar döndürmemelidir.

Özet: LSP: Bir base sınıf veya interface hangi davranışı vaat ediyorsa, ondan türeyen tüm sınıflar da bu davranışı düzgün şekilde gerçekleştirebilmelidir. Örneğin base yapıda Pay() metodu varsa, alt sınıflar bu ödeme işlemini gerçekten yapabilmelidir. Eğer bir ödeme türü Pay() işlemini desteklemiyorsa, o yapıdan türememelidir.

Örnek (LSP İHLAL ÖRNEĞİ)

bu LSP ye uymaz. çünkü ben c# a diyorum ki senin Pay şeklinde metotun var ve bu metot içerisinde ödeme başarılı şekilde yapılabilecek. Fakat ben taksit seçeneğini seçtiğimde olmuyor. Bu LSP ye aykırıdır

Örnek 2 (LSP Örneği)

Bu yapı LSP’ye uygundur çünkü IPayment interface’ini implement eden sınıflar Pay() davranışını gerçekten destekler. Alt sınıflar, üst tipin yerine kullanıldığında programın beklenen davranışını bozmaz.

I – Interface Segregation Principle

Bir interface’i implement eden sınıf, kullanmayacağı metotları yazmak zorunda kalmamalıdır.

ISP ye Aykırı bir örnek

Burada hayvanlar iş yapmaz. Bu yüzden bu sınıfı implement etmemelidir. Yani work sınıfım animal class’ında boş kaldı. Bu durum ISP’ye aykırıdır

ISP Örnek

Doğru kullanım bu şekilde olmalıdır. Bu kullanımda herhangi boş bir sınıf yok yani kullanılmayan bir sınıf yok.

Dependency Inversion Principle

Dependency Inversion Principle Nedir?

Bir class, başka bir class’a doğrudan bağlı olmamalıdır. Bunun yerine interface gibi soyut yapıya bağlı olmalıdır. Mesela bir OrderService sınıfımız olsun ve bu sınıf ödeme almak istiyor olsun. Eğer OrderService direkt olarak CreditCardPayment sınıfını oluşturuyorsa yani

var payment = new CreditCardPayment();

OrderService, artık CreditCardPayment sınıfına tight coupling yani sıkı sıkıya bağımlı olur. DIP der ki: OrderService sınıfımız, CreditCardPayment’a bağlı değil IPayment şeklinde bir interface e bağlı olsun.

Neden Kullanılır?

DIP kullanılmazsa, yarın kredi kartı yerine CashPayment, BankTransferPayment geldiğinde, ana sınıfımın kodunu sürekli değiştirmem gerekir.

DIP kullanıldığında ana sınıfımı değiştirmem sadece dışarıdan hangi servisi vereceğime karar veririm

Dependency Inversion Principle Olmadan Örnek

Yarın diğer gün nakit ödeme istediğimizde:

Dependency Inversion Principle Kullanarak Örnek

Yani Dependency Inversion Prensibi, bir sınıfın concrete sınıflara değil onların abstraction’larına bağlı olması gerektiğini önerir. Böylece o sınıf herhangi bir somut sınıfa bağımlı olmayacak