SOLID Prensipleri Gerçek Projelerde Nasıl Uygulanır?

Yazılım geliştirmede kalite, sürdürülebilirlik ve okunabilirlik denince ilk akla gelen kavramlardan biri SOLID prensipleridir. Bu beş ilke, özellikle nesne yönelimli programlama yapan geliştiriciler için yazılım mimarisinin temel taşlarını oluşturur. Ancak bu prensiplerin gerçek projelerde nasıl uygulandığına dair net örnekler olmadan, kavramlar çoğu zaman soyut kalabilir.

Bu yazıda, her bir SOLID ilkesini açıklayacak ve uygulamada karşılığı olan senaryolarla örnekleyeceğiz.


S — Single Responsibility Principle (Tek Sorumluluk İlkesi)

“Bir sınıf sadece tek bir sorumluluğa sahip olmalı.”

Gerçek Hayattan Örnek:
Bir e-ticaret uygulamasında OrderService sınıfının hem sipariş oluşturma, hem fatura yazdırma, hem de e-posta gönderme işini yapması sıkça rastlanan bir hatadır. Bu sınıfın sorumlulukları ayrılmalı:

tsCopyEdit// Doğru Yaklaşım
class OrderService {
  createOrder(data: OrderData): void { /*...*/ }
}

class InvoiceService {
  generateInvoice(orderId: number): Invoice { /*...*/ }
}

class NotificationService {
  sendEmail(to: string, subject: string): void { /*...*/ }
}

O — Open/Closed Principle (Açık/Kapalı İlkesi)

“Yazılım bileşenleri geliştirilmeye açık, ancak değişime kapalı olmalı.”

Gerçek Hayattan Örnek:
Bir ödeme sistemi farklı ödeme yöntemlerini desteklemeli ama her yeni ödeme yöntemi eklendiğinde mevcut kod değiştirilmemelidir. Bunun yerine arayüz ve kalıtım kullanılabilir:

tsCopyEditinterface PaymentMethod {
  pay(amount: number): void;
}

class CreditCardPayment implements PaymentMethod {
  pay(amount: number): void { /*...*/ }
}

class PaypalPayment implements PaymentMethod {
  pay(amount: number): void { /*...*/ }
}

Yeni bir yöntem (örneğin BitcoinPayment) eklemek, mevcut sınıfları değiştirmeden mümkün olur.


L — Liskov Substitution Principle (Yerine Geçme İlkesi)

“Bir sınıfın alt sınıfları, o sınıfın yerine kullanılabilir olmalı.”

Gerçek Hayattan Örnek:
Bir Bird sınıfınız varsa ve Penguin de onun bir alt sınıfıysa, fly() fonksiyonu varsa ama penguen uçamıyorsa, Liskov ihlal edilir.

Yanlış yapı:

tsCopyEditclass Bird {
  fly(): void { /*...*/ }
}

class Penguin extends Bird {
  fly(): void { throw new Error("Can't fly"); }
}

Çözüm: Uçabilen ve uçamayan kuşları ayırmak.

tsCopyEditinterface Flyable {
  fly(): void;
}

class Sparrow implements Flyable { fly() { /*...*/ } }

class Penguin { /* fly yok */ }

I — Interface Segregation Principle (Arayüz Ayrımı İlkesi)

“Kullanıcılar ihtiyaç duymadıkları metodlara bağımlı bırakılmamalıdır.”

Gerçek Hayattan Örnek:
Bir IMachine arayüzü hem print(), scan(), fax() metodlarını içeriyorsa ama bazı makineler sadece yazıcıysa bu durum hatalıdır.

Çözüm: Küçük ve odaklı arayüzler tanımlanmalı.

tsCopyEditinterface IPrinter {
  print(): void;
}

interface IScanner {
  scan(): void;
}

class SimplePrinter implements IPrinter {
  print(): void { /*...*/ }
}

D — Dependency Inversion Principle (Bağımlılıkların Ters Çevrilmesi)

“Yüksek seviyeli modüller, düşük seviyeli modüllere bağlı olmamalı. İkisi de soyutlamalara bağlı olmalı.”

Gerçek Hayattan Örnek:
Bir uygulama doğrudan MySQLDatabase sınıfını kullanıyorsa, bu sınıfa bağımlıdır. Bunun yerine bir IDatabase arayüzü kullanılmalı:

tsCopyEditinterface IDatabase {
  connect(): void;
}

class MySQLDatabase implements IDatabase {
  connect(): void { /*...*/ }
}

class App {
  constructor(private db: IDatabase) {}

  start(): void {
    this.db.connect();
  }
}

Bu sayede veri kaynağını değiştirmek mümkündür (örn. MongoDB, PostgreSQL).


Sonuç

DinamikUp olarak projelerimizde SOLID prensiplerini uygulayarak hem sürdürülebilir, hem de esnek mimariler kurmaya özen gösteriyoruz. Bu prensipler sadece teorik değil; gerçek dünyadaki problemlerin daha temiz, daha okunabilir ve daha az hata içeren çözümlerle ele alınmasını sağlıyor. Geliştirici ekiplerin ortak bir anlayışla kod yazması, projelerin uzun vadeli başarısının anahtarıdır.


DinamikUp olarak projelerimizde SOLID prensiplerini uygulayarak hem sürdürülebilir, hem de esnek mimariler kurmaya özen gösteriyoruz. Bu prensipler sadece teorik değil; gerçek dünyadaki problemlerin daha temiz, daha okunabilir ve daha az hata içeren çözümlerle ele alınmasını sağlıyor. Geliştirici ekiplerin ortak bir anlayışla kod yazması, projelerin uzun vadeli başarısının anahtarıdır.

#SOLID, #CleanCode, #YazılımMimarisi, #YazılımGeliştirme, #OOP, #BestPractices, #DinamikUp,

Bir yanıt yazın

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