Değişmez / durumsuz singletonlar kötü mü?


12

Son zamanlarda singletonlara karşı bir tür devrim oldu, ancak vatansızlarsa onlarla ilgili bir sorun mu var?

Aşırı konuşmayı biliyorum ve hepsi ... bu sadece singletonlar için değil her şey için geçerlidir.


1
Hayır. Singletonlar prensip olarak fena değil, sadece çok fazla kullanılıyorlar.
Bart van Ingen Schenau

3
Lately ile ne demek istiyorsun?
Manoj R

5
@Jachim Sauer: Neden değiştirmeniz gerekiyor; vatansız ise doğrudan test edebilirsiniz.
m3th0dman

1
Vatansız singletonunuz varsa, temel olarak, Tanrı Sınıfı anti-modeline dönüşme eğilimi olan statik bir yardımcı sınıfınız vardır. Statik yöntemleri genellikle içinde kullanıldığı bağlamda kullanabilirsiniz (veya daha iyisi: C # 'da uzantı yöntemlerini kullanın).
Ocak'ta Spoiler

Yanıtlar:


12
  > Are immutable/stateless singletons bad?
  • Hayır , diğer harici sistemlere bağlı değilse.
    • Örnek: Bir dizenin içindeki html'den kaçan bir Stringutility.
    • Sebep: Birim testlerde, bunu bir sahte / simülatörle değiştirmeye gerek yoktur.
  • Evet senin değişmez / vatansız tekil diğer dış Sistemleri / Hizmetler bağlıdır ve unittesting yapmak istiyorsanız (Izolasyonda test) eğer
    • Örnek: Harici Vergi-Hesap Makinesi-Web Hizmetine bağlı bir Hizmet.
    • Sebep: Bu Hizmetle (tek başına) birim testler yapabilmek için harici Sistemleri / Hizmetleri simüle etmeniz / taklit etmeniz gerekir.

Daha fazla ayrıntı için soğan mimarisine bakın


  • Singleton-lar birim testini (izole olarak) daha zor / imkansız hale getirebilir ve
  • gizli bağımlılıklar / kuplaj @yBee tarafından açıklandığı gibi bir sorun olarak görülebilir

Singletons kullanmamanın başka nedenlerini görmüyorum.


Sınıfınızı (vatansız) bir singleton olmasa bile, test etmek istiyorsanız bu harici web hizmetiyle alay etmelisiniz.
m3th0dman

@ m3th0dman katılıyorum
K3b

10

Her zaman kullanıma bağlıdır. Ben devrim her programcı olarak bu kalıbı öğrenir ki aslında geldiğini düşünüyorlar nesne yönelimli desen. Çoğu, nerede mantıklı ve nerede olmadığı hakkında düşünmeyi unutur. Bu, elbette, her model için geçerlidir. Sadece kalıpları kullanarak iyi kod veya iyi yazılım oluşturmazsınız.

Durum bilgisi olmayan bir singletonunuz varsa, neden yalnızca statik yöntemler sunan bir sınıf kullanmıyorsunuz (veya statik bir sınıf kullanmıyorsunuz)?

Burada genel olarak küresel değişkenler ve singletonlarla ilgili bazı yayınlar.

Yazar kadar katı olmazdım ama o da bir singletona ihtiyacınız olduğunu düşündüğünüz çoğu durumda, buna gerçekten ihtiyacınız olmadığını gösteriyor.


1
Neden statik yöntemlerle bir sınıf kullanmıyorsunuz? Örneğin kalıtım ...
m3th0dman

3
@ m3th0dman: Kalıtım için iyi bir yer gibi görünmüyor.
Billy ONeal

@BillyONeal Etki alanı modelini biliyorsanız, bu şekilde modellenecek olan bir şey miras için iyi veya kötü olduğunu söyleyebilirsiniz ...
m3th0dman

2
@ m3th0dman: Erm, no. Etki alanı modeli hakkında hiçbir şey bilmeden oldukça olumlu olabilirim. Kalıtım polimorfik davranış içindir. Ama tek bir kişi olarak, polimorfik davranışınız olmayacak.
Billy ONeal

1
@ m3th0dman: Çünkü singleton nesnesini elde etmek için çağrı sitesinde singleton'un adını belirtmeniz gerekir. Bu, polimorfik davranış kullanmadığınız anlamına gelir. Bu, bileşimin kalıtımdan çok daha esnek olduğu anlamına gelir.
Billy ONeal

7

Değişmez bir vatansız singleton'un statik bir sınıfın yapamayacağı hiçbir şey yoktur.

-> Instance () öğesinin oluşturduğu ekstra karmaşıklık düzeyini eklemek için hiçbir neden yoktur, oysa statik bir yönteme yapılan düz çağrı daha net, kaynaklar açısından daha muhafazakar ve muhtemelen daha hızlı olacaktır.

Yanlış oldukları değil. Bunu yapmanın daha iyi bir yolu var. Normal ("durum bilgisi olan") tektonların gitmek için doğru yol olduğu senaryolar vardır. Singleton ile kötülük, genellikle küresel değişkenlerle aynı kötü sonuçlarla istismar edilmeleri, ancak singleton kullanmanın basitçe doğru olduğu belirli durumlar vardır. Vatansızlar için böyle bir durum yok.


Bahse girerim, bir Singleton'un bazı avantajları olan bazı durumlar oluşturabilirsiniz. Senaryoya ve Programlama Dili'ne bağlı olarak (örn. Tembel yüklemeden yararlanma)
StampedeXV

1
@StampedeXV: Evet, kesinlikle durum bilgisi olan bir single. Vatansız ve değişmez bir örnek - herhangi bir örnek duymak gerçekten çok isterdim ama nefesimi tutmuyorum.
SF.

Tamam, bir noktan var. Cevabınızı biraz genelleştirdim. Değişmez vatansızlar için de bir avantaj görmüyorum.
StampedeXV

1
Sadece statik fonksiyonlara sahip sınıflarda, büyük bir sınır olan kalıtım / polimorfizm kullanamazsınız ...
m3th0dman

1
Değişmez bir vatansız singleton'un statik bir sınıfın yapamayacağı hiçbir şey yoktur. iyi, statik yöntemler bir arayüz uygulayamaz, hangi bir singleton olabilir
Michal M

3

Singleton ile ilgili temel sorun, kesişen endişeler senaryosunda kullanıldığında özellikle bağımlılıkları ve kuplajları gizlemesidir. Bkz Singletons Patolojik Yalancılar veya Neden Singletons Evil olan ileri okuma için.

Diğer taraftan, kötüye kullanılmazsa, daha az tekil bir durum yardımcı olabilir ve performansı artırabilir. Bir örnek düşünün:

interface Interface
{
    void Method();
}

class StatelessSingleton : Interface
{
    public static readonly StatelessSingleton Instance = new StatelessSingleton();
    private StatelessSingleton() { }

    public void Method() { }
}

class User
{
    public User(Interface i) { /* ... */ }
}

Burada, StatelessSingleton, Arayüzün varsayılan uygulaması olarak işlev görür ve Kullanıcı yapıcısına yerleştirilir. Sabit kodlu bağlantı ve gizleme bağımlılıkları yoktur. Temel arabirim nedeniyle statik bir sınıf kullanamıyoruz ancak varsayılanın birden fazla örneğini oluşturmak için hiçbir neden yok. Bu yüzden vatansız bir singleton uygun bir seçim gibi görünüyor.

Ancak, varsayılan bir uygulama için başka bir model kullanmalıyız:

class Implementation : Interface
{
    private readonly Action _method;

    public Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

StatelessSingleton ile ilgili performansı vurur ancak Arayüzün genel bir uygulamasını oluşturur. Benzer çözüm IProgress arayüzü tarafından da kullanılır .

Yine de, neden varsayılan davranışın birden fazla uygulanmasına izin verilsin? Ancak ikisini birleştirebiliriz:

class Implementation : Interface
{
    public readonly Implementation Default = new Implementation();

    private readonly Action _method;

    private Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

Sonuç olarak, Singletonların yararlı olduğu yerler (varsayılan olarak tasvir edildiği gibi) olduğuna inanıyorum. Singleton'un ana tanımı , bir sınıfın birden fazla örneğini oluşturmaya izin vermediğini belirtir . Nükleer güç gibi. Enerji veya bomba üretebilir. Bu insana bağlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.