SOLID Prensipleri, Temiz kod yazmayı öğrenin!
Kod yazarken sadece “çalışıyor mu?” diye sormak yetmez. Asıl soru zaman geçtikten sonra bu koda bakan birisi ne okuyabilir? Tam da bu…
SOLID Prensipleri, Temiz kod yazmayı öğrenin!
Kod yazarken sadece “çalışıyor mu?” diye sormak yetmez. Asıl soru zaman geçtikten sonra bu koda bakan birisi ne okuyabilir? Tam da bu sorunun cevabı için İyi ve temiz kod yazmanın 5 prensibi SOLID.
1. Single Responsibility (SRP) (Tek Sorumluluk İlkesi)
Kural: Bir sınıf sadece tek bir işten sorumlu olmalı. Eğer bir sınıfın birden fazla işi var ise, bakımı ve güncellenmesi zorlaşabilir.
Yanlış olan:
public class Invoice
{
public void CalculateTotal()
{
// Fatura toplamını hesaplama işlemi
Console.WriteLine("Toplam Hesaplandı.");
}
public void SaveToDatabase()
{
// Faturayı veritabanına kaydetme işlemi
Console.WriteLine("Veri tabanına kaydedildi."); //Hesaplama + kaydetme işlemi tek bir sınıfta yapılıyor,
//bu da tek sorumluluk prensibine aykırıdır.
}
}
Doğru olan :
// Tek sorumluluk prensibine uygun hale getirmek için, hesaplama ve kaydetme işlemlerini ayrı sınıflara bölebiliriz:
public class InvoiceCalculate
{
public void CalculateTotal()
{
// Fatura toplamını hesaplama işlemi
Console.WriteLine("Toplam Hesaplandı.");
}
}
public class InvoiceRepository
{
public void SaveToDatabase(InvoiceCalculate invoiceCalculate)
{
// Faturayı veritabanına kaydetme işlemi
Console.WriteLine("Veri tabanına kaydedildi.");
}
}
Yaygın yanlış anlama: “Tek sorumluluk = tek metod” değildir. Bir sınıf birden fazla metod içerebilir; önemli olan tüm bu metotların aynı sorumluluğa hizmet etmesidir.
Farklı doğru kullanım :
public class InvoiceCalculator
{
// Birden fazla metod, ama tek sorumluluk: hesaplama
public double CalculateTotal() { ... }
public double CalculateTotalWithDiscount(double discount) { ... }
}
2. Open/Closed Principle (OCP) (Açık/Kapalı Prensibi)
Kural: Sınıflar, mevcut kodlarını değiştirmeye gerek kalmadan yeni özelliklerle kolayca genişletebilmelidir. Bu, yeni işlevler eklemenin yanlışlıkla sistemi bozmamasını sağlar.
Yanlış olan:
public double CalculateArea(String shape, double value)
{
if (shape == "circle")
return Math.PI * value * value; // dairenin alanı: πr²
else if (shape == "square")
return value * value; // karenin alanı: a²
else
throw new ArgumentException("Bilinmeyen şekil");
}
// Bu sınıf, yeni bir şekil eklemek istediğimizde mevcut kodu değiştirmemiz gerektiğinden açık/kapalı prensibine aykırıdır.
Doğru olan:
public abstract class Shape
{
public abstract double Area();
}
public class Circle : Shape
{
public double Radius { get; set; }
public override double Area() => Math.PI * Radius * Radius; // dairenin alanı: πr²
}
public class Square : Shape
{
public double Side { get; set; }
public override double Area() => Side * Side; // karenin alanı: a²
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public override double Area() => Width * Height; // dikdörtgenin alanı: w * h
}
3. Liskov Substitution Principle (LSP) (Liskov’un Yerine Geçme İlkesi)
Kural: Alt sınıflar, üst sınıflarının yerine sorumsuz bir şekilde çalışmalıdır. Bu, bir alt sınıf kullandığınızda, hatalara neden olmadan üst sınıf gibi davranması gerektiği anlamına gelir.
Yanlış Kullanım:
public class Bird
{
public virtual void Fly() => Console.WriteLine("Uçuyor...");
}
public class Pengiun : Bird
{
public override void Fly() => throw new NotImplementedException("Penguenler uçamaz!");
}
Bu örnekte, Pengiun sınıfı Bird sınıfından türetilmiş olmasına rağmen,Fly() metodunu geçersiz kılarak beklenen davranışı değiştirmektedir.
Doğru kullanım:
public abstract class Bird
{
public abstract void Eat();
}
public interface IFlyable
{
void Fly();
}
public class Sparrow : Bird , IFlyable
{
public override void Eat() => Console.WriteLine("Serçe yemek yiyor.");
public void Fly() => Console.WriteLine("Serçe uçuyor.");
}
public class Pengiun : Bird
{
public override void Eat() => Console.WriteLine("Penguen yemek yiyor.");
//Penguenler uçamadığı için IFlyable interface'ini uygulayamıyoruz.
}
4. Interface Segregation Principle (ISP) (Arayüz Ayırma İlkesi)
Kural: Sınıflar kullanmadıkları, yöntemleri uygulamaya zorlanmamalıdır. Birçok yöntemle büyük bir arayüze sahip olmak yerine, onu daha küçük olanlara bölün. (Bu ilkemiz Liskov’un Yerine Geçme İlkesi ile çok benzerdir fakat karıştırılmaması gerekir.)
Yanlış kullanım:
public interface IWorker
{
void Work();
void Eat();
}
public class Robot : IWorker
{
public void Work() => Console.WriteLine("Robot çalışıyor.");
public void Eat() => throw new NotImplementedException("Robotlar yemek yemez.");
}
Bu örnekte, Robot sınıfı IWorker arayüzünü uygulamak zorunda kalır, ancak Eat() metodu geçersiz kılarak beklenen davranışı değiştirmektedir.
Doğru kullanım:
public interface IWorkable
{
void Work();
}
public interface IFeedable
{
void Eat();
}
public class Human : IWorkable , IFeedable
{
public void Work() => Console.WriteLine("İnsan çalışıyor...");
public void Eat() => Console.WriteLine("İnsan yemek yiyor...");
}
public class Robot : IWorkable
{
public void Work() => Console.WriteLine("Robot çalışıyor...");
// Robot sınıfı sadece IWorkable arayüzünü uygulayarak, yemek yeme işlevini zorunlu kılmadan çalışabilir.
}
5. Dependency Inversion Principle (DIP) (Bağımlılığı Tersine Çevirme İlkesi)
Kural: Üst düzey modüller (programınızın önemli kısımları) düşük düzey ayrıntılara bağlı olmamalıdır. Her ikisi de soyutlamalara (arayüzler gibi) dayanmalıdır.
Yanlış Kullanım:
public class EmailSender
{
public void SendEmail(string message)
{
Console.WriteLine($"Email gönderildi: message={message}");
}
}
public class NotificationService
{
private readonly EmailSender _emailSender = new EmailSender();
public void SendNotification(string message)
{
_emailSender.SendEmail(message);
}
// Bu örnekte, NotificationService sınıfı doğrudan EmailSender sınıfına bağımlıdır, bu da bağımlılık ters çevirme prensibine aykırıdır.
}
Doğru Kullanım:
public interface IMessageSender
{
void Send(string message);
}
public class EmailSender : IMessageSender
{
public void Send(string message) => Console.WriteLine($"Email gönderildi: message={message}");
}
public class SmsSender : IMessageSender
{
public void Send(string message) => Console.WriteLine($"SMS gönderildi: message={message}");
}
public class Notification
{
private readonly IMessageSender _messageSender;
public Notification(IMessageSender messageSender) => _messageSender = messageSender;
public void SendNotification(string message) => _messageSender.Send(message);
}
Notification sınıfı, IMessageSender arayüzüne bağımlıdır, bu da farklı mesaj gönderme yöntemlerini kolayca değiştirebilmesini sağlar.
메타데이터
- post_id
- b4378bd1bb7d
- slug
- solid-prensipleri-temiz-kod-yazmayı-öğrenin-b4378bd1bb7d
- url
- https://medium.com/@menes.yilm/solid-prensipleri-temiz-kod-yazmay%C4%B1-%C3%B6%C4%9Frenin-b4378bd1bb7d
- canonical_url
- https://medium.com/@menes.yilm/solid-prensipleri-temiz-kod-yazmay%C4%B1-%C3%B6%C4%9Frenin-b4378bd1bb7d
- author_url
- https://medium.com/@menes.yilm
- status
- ok
- fetched_at
- 2026-06-12 07:40:50