Sobes.tech
Middle+

Singleton deseni neden anti-deseni olarak kabul edilir?

sobes.tech yapay zeka

AI'dan gelen yanıt

Singleton, SOLID ilkelerini ihlal eder ve testleri zorlaştırır:

  • Tek sorumluluk ilkesi (SRP) ihlali: Sınıf hem kendi mantığından hem de yaşam döngüsünü yönetmekten (yaratma ve tek örneğe erişim) sorumludur.
  • Açık/Kapalı ilkesi (OCP) ihlali: Singleton sınıfının işlevselliğini genişletmek, kodunu değiştirmeden zor olabilir.
  • Liskov Yerine Koyma İlkesi (LSP) ihlali: Singleton sınıfının alt tipleri, Singleton uygulamasının özellikleri nedeniyle temel tipin sözleşmelerini karşılamayabilir.
  • Bağımlılıkların Tersine Çevirme İlkesi (DIP) ihlali: Modüller, Singleton'un belirli bir uygulamasına bağımlıdır, soyutlamalara değil. Bu, Singleton nesnesini mock veya stub ile değiştirmeyi zorlaştırır.
  • Test sorunları: Singleton örneği küresel bir durumdur, bu da testlerin paralel yürütülmesini ve test senaryolarının izolasyonunu zorlaştırır. Singleton nesnesinin bağımlılıklarını değiştirmek zordur.
  • Gizli bağımlılıklar: Singleton kullanımı, modüller arasındaki bağımlılıkları gizler çünkü bunlar açıkça iletilmez.
  • Çok iş parçacıklı ortam sorunları: Çok iş parçacıklı ortamda Singleton örneğine erişimi senkronize etme ihtiyacı, kodu karmaşıklaştırabilir ve potansiyel hatalara yol açabilir.
  • Kullanım ömrü yönetimi zorluğu: Singleton nesnesinin yaşam döngüsünü yönetmek ve onu yok etmek belki de açık değildir.

Singleton yerine, genellikle bağımlılık enjeksiyonu veya Service Locator kullanmak, nesnelerin yaşam döngüsünü ve erişimini yönetmek için daha iyidir.

Aşağıda, bahsedilen sorunları gösteren tipik bir Swift Singleton uygulaması örneği bulunmaktadır:

// Singleton.swift
class DataManager {
    static let shared = DataManager() // Küresel erişim noktası, bağımlılığı gizler
    
    private init() { // Özel yapıcı, mock nesnelerin oluşturulmasını zorlaştırır
        // Kaynakların veya durumun başlatılması
    }
    
    func fetchData() -> [String] {
        // Veri alma mantığı (örneğin, ağ veya veritabanından)
        // Bu mantık, durum yönetimi ve erişimle ilgilidir, SRP'yi ihlal eder
        return ["Item 1", "Item 2"]
    }
}

// Kullanım örneği
// DataManager.shared'a doğrudan bağımlı modül
class ViewController {
    func displayData() {
        let data = DataManager.shared.fetchData() // Gizli bağımlılık
        print(data)
    }
}

// ViewController testleri zor hale gelir:
// DataManager.shared'ı nasıl mock nesne ile değiştirebilirim?
// DataManager.shared küresel olduğu için testleri nasıl izole ederim?