Statik sınıf ve tekli kalıp arasındaki fark nedir?


1767

Statik bir sınıf ile tektonlu bir model arasında hangi gerçek (yani pratik) fark vardır?

Her ikisi de somutlaştırılmadan çağrılabilir, her ikisi de yalnızca bir "Eşgörünüm" sağlar ve hiçbiri iş parçacığı için güvenli değildir. Başka bir fark var mı?


4
Dil uygulamasına ve kullanım alışkanlıklarınıza bağlı olarak, yöntemi kullanmak istediğiniz her seferinde çağırmanın yükü nedeniyle bir Singleton daha az verimli olabilirgetInstance() (muhtemelen çoğu durumda önemli değildir ).
Çok fazla php

5
Şimdiden birçok cevap var. Aslında, yöntemlerin sadece işlevler singletonolduğu bir nesne static, bir OO olmayan varlık.
fastcodejava


4
Üçüncü tarafların sınıfın uygulanmasını sağlamasına izin vermek istediğinizde bir fark vardır. Bu durumda, genellikle bir Fabrika desenine de ihtiyacınız vardır. Bkz. Agiletribe.wordpress.com/2013/10/08/…
AgilePro

IMO bu cevap çok iyi özetliyor stackoverflow.com/questions/14097656/…
Dave

Yanıtlar:


1251

Size bir singleton veya statik bir yöntemin iş parçacığı için güvenli olmadığını söyleyen nedir? Genellikle her iki gerektiği evreli olduğu uygulanacaktır.

Bir singleton ve bir grup statik yöntem arasındaki en büyük fark, singletonların arayüzler uygulayabilmesidir (veya yararlı temel sınıflardan türetilebilir, ancak bu benim deneyimime göre daha az yaygın olsa da), bu yüzden singletonun etrafında "başka bir uygulama.


29
Eğer tercih ederseniz, ikisi de doğal olarak threadsafe değildir, onları threadsafe yapmak zorundasınız, ikisi de, bu yüzden orada bir fark yok.
Jorge Córdoba

119
Eğer bir şeyin bir örnek verebilir olduğunu iletmenin türleri dışındaki doğal ÅŸan?
Jon Skeet

26
Skeet'e: singleton'un threadsafe olmadığını söyleyen insanlar, iş parçacığı arasında her zaman gereksiz olarak bir singleton'un paylaşıldığı anlamına gelirken, yığın nesneleri ihtiyacınız olduğunda paylaşılır, yani gereksiz senkronizasyon yapmanız gerekmez.

45
@Geek: Singleton'un bir arayüz uyguladığını Foove Fooparametre olarak a yönteminin olduğunu hayal edin . Bu kurulumla, arayanlar singletonu uygulama olarak kullanmayı seçebilir veya farklı bir uygulama kullanabilirler. Yöntem singletondan ayrılır. Sınıfın statik yöntemlere sahip olduğu durumla karşılaştırın - bu yöntemleri çağırmak isteyen her kod parçası sınıfa sıkıca bağlıdır, çünkü hangi sınıfın statik yöntemleri içerdiğini belirtmesi gerekir.
Jon Skeet

10
@AmirBareket: Yine de singleton tasarım modeline göre bir singleton değil - eğer sınıfın kendisi birden fazla örneğin yaratılmasına izin veriyorsa, fabrikanın ne yaptığından bağımsız olarak singleton IMO değildir.
Jon Skeet 10'14

476

Gerçek cevap Jon Skeet, burada başka bir forumda .

Tekli tek bir oluşturulan örneğe erişime izin verir - bu örnek (ya da daha doğrusu, bu örneğe bir referans) diğer yöntemlere parametre olarak geçirilebilir ve normal bir nesne olarak değerlendirilebilir.

Statik sınıf yalnızca statik yöntemlere izin verir.


64
Statik getInstance () yöntemini çağırarak aynı örneğe hemen hemen her yerden erişebiliyorsanız neden bir Singleton'ı parametre olarak iletesiniz?
Henrique Ordine

23
@HenriqueOrdine Yani mevcut koda sığabilir ve bir arayüz sağlayabilir?

6
@HenriqueOrdine Statik yöntemlerden oluşan bir sınıftan değil, statik sınıftan bahsediyorlar. Statik sınıf somutlaştırılamaz. Bununla birlikte, statik yöntemler içeren (statik olmayan) bir sınıf örneğini iletirseniz, örnek üzerinde statik yöntemleri çağıramazsınız.
Goran

3
Statik sınıf nedir? En azından Java'da böyle bir şey yok.
Henrique Ordine

16
@ Goran Başlangıçta ifadelerinizle çok karışmıştım. "Bir örnek üzerinde statik yöntemleri çağıramazsınız" dediniz. Bunu, "somutlaştırılmış bir nesneye başvurunuz varsa, sahip olabileceği statik yöntemleri çağıramazsınız" şeklinde okudum. Tabii ki yanlış. Birkaç kez tekrar okuduktan sonra "statik yöntemlerden sınıfta statik olmayan nesnelere erişemezsiniz" demek istediğini düşünüyorum. Bu yanıta rastlayan ve yorumlarınızı okuyan bu kavramlarda yeni olan herkes için açıklığa kavuşturmak istiyorum.
Andrew Steitz

359
  1. Tektonlu nesneler Yığın'da saklanır , ancak statik nesneler yığın halinde saklanır .
  2. Biz yapabilirsiniz klonlamak tekil nesne (tasarımcı bunu izin vermemek olmasaydı), ama biz statik sınıf nesnesi değil klon can.
  3. Singleton sınıfları OOP (nesne yönelimli ilkeler) 'i takip eder , statik sınıflar izlemez.
  4. interfaceBir Singleton sınıfıyla bir uygulayabiliriz , ancak bir sınıfın statik yöntemleri (veya örneğin bir C # static class) uygulayamaz .

99
İkinci ifade yanlış. Singleton nesnesini klonlayamayız. Singleton uygulaması bunu reddetmelidir. Gerçekten Singleton'ı klonlayabiliyorsanız, Singleton değil.
Alexander Yancharuk

19
Bu cevap Java için doğru değildir: ne tekton ne de statik yığını kullanır.
AgilePro

72
# 1 önemli değil. # 2, hatalı bir uygulamayı açıklar. # 3 tamamen haksızdır.
Casey

31
Statik nesne yığın halinde nasıl saklanabilir? Bir yöntemi çağırdığınızda yeni yığın çerçevesi oluşturulur, yöntemin yerel değişkenlerini depolar, yöntem döndüğünde bu yığın çerçevesi kaldırılır ve bu yerel değişkenler kaybolur. Emin yığın hızlıdır, ancak statik nesneleri depolamak uygun değildir.
mike_m

23
Bu konudaki oyların sayısını anlayamıyorum. 1) Singleton neden yığın halinde saklanmalıdır? C # veya Java gibi yönetilen dillerde veriler, yerel yöntem değişkenleri / parametreleri hariç, yönetilen bir yığın içinde saklanır. 2) Klonlayabiliyorsanız, düzgün bir şekilde uygulanmış bir singleton değildir. 3) Singleton, bir OOP anti-paterni olarak bilinir; yani mümkünse kaçınmanız gereken bir şey. 4) Doğru olan tek şey bu.
Groo

152

Singleton deseninin statik sınıflara göre birçok avantajı vardır. İlk olarak, tek bir sınıf sınıfları genişletebilir ve arabirimleri uygulayabilirken, statik sınıf sınıfları genişletemez (ancak sınıf üyelerini devralmaz). Statik bir sınıf ilk yüklendiğinde genellikle başlatılırken, potansiyel sınıf yükleyici sorunlarına yol açan bir single tembel veya asenkron olarak başlatılabilir. Bununla birlikte, en önemli avantaj, tektonların, kullanıcılarını yalnızca bir örnek olduğunu varsaymaya zorlamadan polimorfik olarak ele alınabilmesidir.


10
İyi, pragmatik puanlar için +1. Singleton paterni genel olarak aşırı kullanılır, ancak uygun olduğu birkaç durum vardır. Ayrıca bakınız: agiletribe.wordpress.com/2013/10/08/…
AgilePro

3
Polimorfik olmanın avantajı konusunda haklısınız. Bu en önemli nokta
Ahmad

İç içe statik sınıf arabirimi uygulayabilir. Kodlamayı deneyin, işe yarayacak. Herhangi bir hata olmadan kodu derleyebilir.
nanosoft

75

staticsınıflar devlete ihtiyaç duyan hiçbir şey için değildir. Bir grup işlevi bir araya getirmek için yararlıdır, yani Math(veya Utilsprojelerde). Sınıf adı bize sadece fonksiyonları bulabileceğimiz bir ipucu veriyor ve başka bir şey yok.

Singletonbenim en sevdiğim desen ve bunu tek bir noktada yönetmek için kullanıyorum. staticSınıflardan daha esnektir ve durumunu koruyabilir. Arabirimleri uygulayabilir, diğer sınıflardan miras alabilir ve mirasa izin verebilir.

Arasında seçim yapılmasına yönelik Kuralım staticve singleton:

Bir arada tutulması gereken bir grup işlev varsa, o zaman staticseçimdir. Bazı kaynaklara tek erişime ihtiyaç duyan her şey, a singleton.


16
Statik sınıflar durumu kurtarmak için neden hiçbir şey yapmasın ki?
Trisped

12
@Trisped: Başlatma veya sonlandırma üzerinde kesin bir kontrole sahip değilsiniz.
Xaqron

7
beni "Singleton benim en sevdiğim model" de kaybettin Singleton o kadar keskin bir köşedir ki, bir desen olduğu kadar bir anti-desen olarak düşünülmelidir. Sınıflar statik durumlara sahip olabilirler, bu da statik durumun tekil değerlerden daha "tek erişim" olması durumunda tek erişimdir, çünkü çoğu tekil uygulama bozuktur. singleton'ı klonlayabilirsiniz, oysa statik benzersiz olmak için tanım tarafından kutsanır.
PoweredByRice

1
Devleti korumak ne anlama geliyor? Devlet nedir?
Kyle Delaney

2
@KyleDelaney: StateBir nesnenin genellikle zaman içinde değişen farklı özelliklerinin birleşimidir. Resmi tanım için Google'ı kullanabilirsiniz.
Xaqron

65

Statik Sınıf: -

  1. Statik sınıf örneği oluşturamazsınız.

  2. Sınıfı içeren program veya ad alanı yüklendiğinde .NET Framework ortak dil çalışma zamanı (CLR) tarafından otomatik olarak yüklenir.

  3. Statik Sınıfın yapıcısı olamaz.

  4. Statik sınıfı yönteme geçiremeyiz.

  5. Statik sınıfı, C # içindeki başka bir Statik sınıfa devredemeyiz.

  6. Tüm statik yöntemlere sahip bir sınıf.

  7. Daha iyi performans (statik yöntemler derleme zamanında birleştirilir)

Singleton: -

  1. Nesnenin bir örneğini oluşturabilir ve yeniden kullanabilirsiniz.

  2. Singleton örneği, kullanıcı ilk istediğinde oluşturulur.

  3. Singleton sınıfının yapıcısı olabilir.

  4. Singleton sınıfının nesnesini oluşturabilir ve yönteme iletebilirsiniz.

  5. Singleton sınıfı Kalıtım konusunda herhangi bir kısıtlama söylemez.

  6. Tek sınıftaki nesneleri statik sınıftan atabiliriz.

  7. Yöntemler geçersiz kılınabilir.

  8. İhtiyaç olduğunda tembel yüklenebilir (statik sınıflar her zaman yüklenir).

  9. Arabirimi uygulayabiliriz (statik sınıf arabirimi uygulayamaz).


13
Statik sınıfların yapıcıları vardır: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Tomer Arazy

2
Evet, statik, bu sınıfın içinde yer alan yapıcıya sahip olabilir. Sınıftaki herhangi bir statik yöntem çağrıldığında bu çağrılır.
rahulmr

Derleme zamanında singleton için, HEAP belleğinde saklanır, ancak bir kez somutlaştırılırsa STACK içinde saklanır mı?
Luminous_Dev

@Luminous_Dev Hayır. Herhangi bir singleton örneği, günün sonunda bir nesne örneğidir. Şüphesiz yığın üzerinde depolanacak.
RBT

1
@rahulmr Önemli ayrım: kurucu ayrıca ilk (yalnızca AKA) örneği oluşturulmadan önce çağrılır.
CoolOppo

53

Statik sınıf, daha iyi bir kelimenin "işlevler" olacağı yalnızca statik yöntemlere sahip olan sınıftır. Statik bir sınıfta yer alan tasarım stili tamamen prosedüreldir.

Singleton ise OO tasarımına özgü bir modeldir. Tüm ömrü boyunca bu rolün sadece bir örneğinin olmasını sağlayan bir yaratma prosedürü ile (polimorfizm gibi doğal olan tüm olasılıkları olan) bir nesnenin örneğidir.


1
polimorfizm singletonlarla hiç

32
Demek düşünüyorsun. Ben farklı düşünüyorum. ;) Örneğin, bir arabirim döndüren tek bir fabrika düşünün. Bir ISingleton aldığınızı biliyorsunuz (ve sonsuza kadar aynıdır), ancak hangi uygulamada olması gerekmez.
Morendil

İç içe statik sınıf da örnek yöntemleri olabilir, sadece statik yöntemlerle sınırlı değildir .. Kodlayın ve görebilirsiniz.
nanosoft

Daha güzel bir nesne modeline (örneğin Ruby) sahip dillerde, sınıflar da nesnedir. Statik bir sınıfın "tamamen prosedürel" yönü, dil tarafından uygulanan keyfi bir kısıtlamadır.
Maksimum

36

Singleton deseninde, singleton'u türetilmiş bir türün örneği olarak oluşturabilirsiniz, bunu statik bir sınıfla yapamazsınız.

Hızlı Örnek:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer

39
Gerçekten tek bir desen değil, bana fabrika gibi görünüyor.
vava

10
Aslında, ikisi arasındaki temel fark, Singleton'un tek nesnesini "önbelleğe alacağı" ve aynı nesneyi döndürmeye devam etmesi. Fabrika kalıbı yeni örnekler yaratacaktır.
Mystic

12
O zaman proxy-singleton :)
vava

3
Hmm, Singleo'nun bu çeşitliliğini MonoState olarak biliyorum.
Huppie

örnek fabrika modelidir
Rajavel D

26

Jon Skeet'in Cevabı'nı genişletmek için

Bir singleton ve bir grup statik yöntem arasındaki en büyük fark, singletonların arabirimleri uygulayabilmesidir (veya daha az yaygın IME olmasına rağmen yararlı temel sınıflardan türetilebilir), böylece singletonun "sadece başka bir" uygulama gibi geçebilmesidir.

Ünite bir sınıfı test ederken teklitonlarla çalışmak daha kolaydır. Tektonları parametre olarak ilettiğiniz her yerde (yapıcılar, ayarlayıcılar veya yöntemler) bunun yerine singleton'un alaycı veya saplanmış sürümünü değiştirebilirsiniz.


Doğrudan bir single alay edebileceğinizi sanmıyorum. Singleton ve alay sınıfının her ikisinin de uyguladığı bir arabirim bildirmeniz gerekmez mi?
Ellen Spertus

@espertus Neden singletonunu alay edemiyorsun? Mockito kullanılan örnek MySingleton mockOfMySingleton = mock(MySingleton.class).
Mike Rylander

haklısın, yansımayı kullanan mockito gibi araçlarla alay edebilirsin. Demek istediğim, onu alt sınıflandırarak ve yöntemlerini geçersiz kılarak doğrudan alay edemezsiniz.
Ellen Spertus

@espertus Neden olmasın? Test ettiğiniz nesneyi somutlaştırdığınızda, orijinali kullanacağınız her yerde singletonunuzun alt sınıf uygulamasını değiştirebilirsiniz. Örn:new ClazzToTest(mockSingleton);
Mike Rylander

Mockito'yu kullanmadım, ancak özel bir kurucuya sahip bir sınıfı nasıl sınıflandırabilirsiniz, bu da yansıma kullanmak dışında singletonlar için geçerlidir? İlgili tartışmalar: stackoverflow.com/questions/2302179/mocking-a-singleton-class stackoverflow.com/questions/15939023/…
Ellen Spertus

23

İşte iyi bir makale: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Statik sınıflar

  • tüm statik yöntemlere sahip bir sınıf .
  • daha iyi performans (statik yöntemler derleme zamanında birleştirilir)
  • yöntemleri geçersiz kılamaz, ancak yöntem gizlemeyi kullanabilir. ( Java'da yöntem gizleme nedir? JavaDoc açıklaması bile kafa karıştırıcıdır )

    public class Animal {
        public static void foo() {
            System.out.println("Animal");
        }
    }
    
    public class Cat extends Animal {
        public static void foo() {  // hides Animal.foo()
            System.out.println("Cat");
        }
    }
    

Singleton

Özetle, yalnızca util yöntemlerini tutmak ve Singleton'u her şey için kullanmak için statik sınıflar kullanırdım.


Düzenlemeler


4
Java hakkında bilmiyorum, ancak .Net'te son iki noktanız yanlış. Statik sınıflar statik properies ve alanlara başvurabilir, bu nedenle eşittirler. Ve tembel yüklendi - statik yapıcı şu durumlarda çalıştırılır: 1) Sınıfın bir örneği oluşturulduğunda. 2) Sınıfın statik üyelerinden herhangi birine başvurulur. 1 uygulanmaz, bu da 2'den ayrılır. Bu nedenle, statik sınıf ilk kez kullanılıncaya kadar yüklenmez.
jmoreno

1
Statik sınıf için, statik yöntemi geçersiz kılamasanız da, statik yöntemi üst öğesinden gizleyebilirsiniz.
Max Peng

eğer Animal animal = new Cat();öyleyse animal.foo();ne olur?
Luminous_Dev

@jmoreno statik sınıf ilk kez kullanılıncaya kadar yüklenmiyor mu? Derleme zamanında yığın bellekte depolandığına inanıyorum. Ve anında erişilir .. değil mi?
Luminous_Dev

@Luminous_Dev: en azından .net için, statik bir sınıf ilk erişildiğinde çalışan bir yapıcıya sahiptir, bu nedenle anında erişilemez. Statik yapıcı teorik olarak sınırsız bir zaman alabilir. Nerede (ya da başka bir sınıfın saklandığı) bir uygulama detayı ise, bu soru ile gerçekten ilgili değildir.
jmoreno

22

Bir singletonun diğer bir avantajı, kolayca serileştirilebilmesidir, bu da durumunu diske kaydetmeniz veya uzaktan bir yere göndermeniz gerekirse gerekebilir.


19

Ben büyük bir OO teorisyeni değilim, ama bildiğim kadarıyla, statik sınıfların Singletons'a kıyasla eksik olduğu tek OO özelliğinin polimorfizm olduğunu düşünüyorum. Ancak buna ihtiyacınız yoksa, statik bir sınıfla elbette miras (arayüz uygulaması hakkında emin değilim) ve veri ve fonksiyon kapsülleme yapabilirsiniz.

Morendil'in "Statik bir sınıfta yer alan tasarım stili tamamen prosedüreldir" yorumu yanılıyor olabilirim ama katılmıyorum. Statik yöntemlerde, tek örnek üyelerine erişen singleton yöntemleriyle tamamen aynı olan statik üyelere erişebilirsiniz.

edit:
Aslında şimdi başka bir fark bir Statik sınıfının program başlangıcında * başlatılması ve programın tüm yaşam süresi boyunca yaşaması, bir singleton açıkça bir noktada başlatılır ve aynı zamanda yok edilebilir olduğunu düşünüyorum.

* ya da dile bağlı olarak ilk kullanımda somutlaştırılabilir diye düşünüyorum.


15
Evet, herkes statik yöntemlere sahip bir sınıfın hala durumu korumak için kullanabileceği özel statik alanlara sahip olabileceğini görmezden geliyor (ve bazılarını genel statik ayarlayıcılar / alıcılar aracılığıyla istemci koduna maruz bırakıyor).
user289463

17

Jon'un noktasını göstermek için Logger statik bir sınıf olsaydı aşağıda gösterilenler yapılamaz. Sınıf SomeClass, ILoggeruygulamanın bir örneğinin yapıcısına iletilmesini bekler .

Bağımlılık enjeksiyonunun yapılabilmesi için singleton sınıfı önemlidir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {

            var someClass = new SomeClass(Logger.GetLogger());
        }


    }

    public class SomeClass 
    {
        public SomeClass(ILogger MyLogger)
        {

        }
    }

    public class Logger : ILogger
    {
        private static Logger _logger;
        private Logger() { }

        public static Logger GetLogger()
        {
            if (_logger==null)
            {
                _logger = new Logger();
            }

            return _logger;
        }

        public void Log()
        {

        }

    }


    public interface ILogger
    {
         void Log();
    }
}

13

Tek birton, IS örneğinin oluşturulduğu normal bir sınıftır, ancak istemci kodundan yalnızca bir kez ve dolaylı olarak gelir. Statik sınıf somutlaştırılmaz. Bildiğim kadarıyla statik yöntemler (statik sınıf statik yöntemler olmalıdır) statik olmayan daha hızlıdır.

Düzenleme:
FxCop Performans kuralı açıklaması: "Örnek verilere veya çağrı örneği yöntemlerine erişmeyen yöntemler statik olarak işaretlenebilir (VB'de Paylaşılır). Bunu yaptıktan sonra, derleyici bu üyelere sanal olmayan çağrı siteleri yayar. her nesne için çalışma sırasında geçerli nesne işaretçisinin boş olmadığından emin olun. Bu, performansa duyarlı kod için ölçülebilir bir performans kazancı sağlayabilir. Bazı durumlarda, geçerli nesne örneğine erişilememesi bir doğruluk sorununu temsil eder. "
Aslında bunun statik sınıflardaki statik yöntemler için de geçerli olup olmadığını bilmiyorum.


11

Singleton somutlaştırılır, sadece şimdiye kadar somutlaştırılmış tek bir örnek vardır, dolayısıyla Singleton'daki tek örnek vardır .

Statik bir sınıf kendisinden başka hiçbir şeyle başlatılamaz.


Java'da statik sınıf çok fazla örneklenebilir. Docs.oracle.com/javase/tutorial/java/javaOO/nested.html adresini okuyun. Ayrıca cevabımı da bakın stackoverflow.com/a/37114702/1406510
nanosoft

8

Temel farklar:

  • Tek sınıf bir örneğe / nesneye sahipken, statik sınıf bir grup statik yöntemdir
  • Singleton, örneğin bir sınıf aracılığıyla statik sınıf genişletilemediğinde genişletilebilir.
  • Öte yandan, SOLID prensiplerinde açık / kapalı prensiplerini destekleyen singleton kalıtsal olarak kalıtsal sınıftan devralınamaz ve kendimizde değişiklik yapmamız gerekir.
  • Tekton nesnesi, örneğe sahip olmadığından statik sınıf parametre olarak iletilemezken yöntemlere geçirilebilir

7

Singleton, test perspektifinden daha iyi bir yaklaşımdır. Statik sınıflardan farklı olarak, singleton arabirimleri uygulayabilir ve sahte örneği kullanabilir ve enjekte edebilirsiniz.

Aşağıdaki örnekte bunu açıklayacağım. GetPrice () yöntemini kullanan isGoodPrice () yönteminiz olduğunu ve tek birtonda yöntem olarak getPrice () yöntemini uyguladığınızı varsayalım.

getPrice işlevselliğini sağlayan singleton:

public class SupportedVersionSingelton {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        // calculate price logic here
        return 0;
    }
}

GetPrice kullanımı:

public class Advisor {

    public boolean isGoodDeal(){

        boolean isGoodDeal = false;
        ICalculator supportedVersion = SupportedVersionSingelton.getInstance();
        int price = supportedVersion.getPrice();

        // logic to determine if price is a good deal.
        if(price < 5){
            isGoodDeal = true;
        }

        return isGoodDeal;
    }
}


In case you would like to test the method isGoodPrice , with mocking the getPrice() method you could do it by:
Make your singleton implement an interface and inject it. 



  public interface ICalculator {
        int getPrice();
    }

Final Singleton uygulaması:

public class SupportedVersionSingelton implements ICalculator {

    private static ICalculator instance = null;

    private SupportedVersionSingelton(){

    }

    public static ICalculator getInstance(){
        if(instance == null){
            instance = new SupportedVersionSingelton();
        }

        return instance;
    }

    @Override
    public int getPrice() {
        return 0;
    }

    // for testing purpose
    public static void setInstance(ICalculator mockObject){
        if(instance != null ){
instance = mockObject;
    }

test sınıfı:

public class TestCalculation {

    class SupportedVersionDouble implements ICalculator{
        @Override
        public int getPrice() { 
            return 1;
        }   
    }
    @Before
    public void setUp() throws Exception {
        ICalculator supportedVersionDouble = new SupportedVersionDouble();
        SupportedVersionSingelton.setInstance(supportedVersionDouble);

    }

    @Test
    public void test() {
          Advisor advidor = new Advisor();
          boolean isGoodDeal = advidor.isGoodDeal();
          Assert.assertEquals(isGoodDeal, true);

    }

}

GetPrice () öğesini uygulamak için statik yöntem kullanma alternatifini kullanmamız durumunda, getPrice () alay etmek zordu. Statik güç taklidi ile alay edebilirsiniz, ancak tüm ürünler bunu kullanamaz.


1
Bu artık iş parçacığı için güvenli değil ve arayüz uygulamasına nasıl eriştiğiniz konusunda genellikle kötü. Tabii, bir arayüze sahip olmak test edilebilirlik için güzel - ama neden bir singleton ile uğraşalım? Sadece bir singleton olmaktan kaçının; üretim için bir sınıfa, test amaçlı bir uygulamaya sahip olun ve ne yaptığınıza bağlı olarak doğru örneği enjekte edin. Singleton'u arayanlarla eşleştirmeye gerek yok.
Jon Skeet

Geri dönüşünüz için teşekkür ederiz. ipliği güvenli hale getirmek çok basittir. Buna ek olarak, önbellekleme için singleton kullanıyorum.
Amir Bareket

1
Evet, her ne kadar anlamsız yük ile. Yine, bir singleton kullanmamak daha basittir.
Jon Skeet

6

Bu tanıma katılıyorum:

" Tek " kelimesi , uygulama yaşam döngüsü boyunca tek bir nesne anlamına gelir;

Statik kapsamı App Domain seviyesinde yani, herhangi bir nesne işaretçisi yoktur.

Ayrıca, her ikisi de iş parçacığı açısından güvenli olacak şekilde uygulanmalıdır.

Şununla ilgili ilginç başka farklılıklar da bulabilirsiniz: Singleton Pattern Versus Static Class


5

Dikkate değer bir fark, Singletons ile birlikte gelen farklı örnekleme.

Statik sınıflarla CLR tarafından oluşturulur ve üzerinde kontrolümüz yoktur. singletons ile, nesne erişilmeye çalışıldığı ilk örnekte somutlaştırılır.


4

Çoğu durumda, bu ikisinin pratik bir farkı yoktur, özellikle de singleton örneği hiçbir zaman çok yavaş değişmez veya değişmezse, örneğin konfigürasyonları tutma.

Ben en büyük fark bir singleton özel bir statik sadece Java sınıfının aksine hala normal bir Java Bean olduğunu söyleyebilirim. Ve bu nedenle, daha birçok durumda bir singleton kabul edilir; aslında varsayılan Spring Framework'ün örnekleme stratejisidir. Tüketici, etrafta dolaşan bir singleton olabilir veya bilmeyebilir, sadece normal bir Java fasulyesi gibi davranır. Gereksinim değişirse ve bunun yerine bir tektonun bir prototip olması gerekiyorsa, ilkbaharda sıkça gördüğümüz gibi, tüketici için bir kod satırı değişikliği olmadan tamamen sorunsuz bir şekilde yapılabilir.

Birisi daha önce statik bir sınıfın yalnızca prosedürel olması gerektiğini söylemişti, örneğin java.lang.Math. Aklımda, böyle bir sınıf asla geçilmemeli ve hiçbir zaman nitelik olarak statik finalden başka bir şey tutmamalıdır. Diğer her şey için, çok daha esnek ve bakımı daha kolay olduğu için tek birton kullanın.


4

Arka uçla bağlantı kuran DB çerçevemize sahibiz. Birden fazla kullanıcı arasında Kirli okumaları önlemek için, herhangi bir zamanda tek bir vakanın mevcut olmasını sağlamak için tekli desen kullandık.

C # 'da statik bir sınıf bir arabirim uygulayamaz. Tek bir örnek sınıfının iş sözleşmeleri veya IoC amaçları için bir arabirim uygulaması gerektiğinde, burada statik sınıf olmadan Singleton desenini kullanıyorum

Singleton, vatansız senaryolarda durumu korumanın bir yolunu sunar

Umarım sana yardımcı olur ..


3
  1. Yavaş yüklenme
  2. Arabirimlerin desteklenmesi, böylece ayrı uygulama sağlanabilir
  3. Türetilmiş türü döndürme yeteneği (lazyloading ve arayüz uygulamasının bir kombinasyonu olarak)

İç içe statik sınıf, java'da arabirimi çok fazla uygulayabilir. İkinci noktanız Yanlış.
nanosoft

3

a. Serileştirme - Statik üyeler sınıfa aittir ve bu nedenle serileştirilemez.

b. Yapıcıyı özel yapmamıza rağmen, statik üye değişkenleri yine de alt sınıfa taşınacaktır.

c. Her şey sadece sınıf yüklemesinde yükleneceğinden tembel başlatma yapamayız.


3

İstemci perspektifinden, statik davranış istemci tarafından bilinir ancak Singleton davranışı bir istemciden gizlenebilir. Müşteri, tekrar tekrar oynadığı tek bir örneğin olduğunu asla bilemeyebilir.


3

Aşağıdakileri okudum ve bunun da mantıklı olduğunu düşünüyorum:

İşle ilgilenmek

Unutmayın, en önemli OO kurallarından biri, bir nesnenin kendisinden sorumlu olmasıdır. Bu, bir sınıfın yaşam döngüsüyle ilgili sorunların, statik gibi dil yapılarına devredilmemesi yerine sınıfta ele alınması gerektiği anlamına gelir.

Hedefe Yönelik Düşünce Süreci kitabından 4. Baskı.


Buna katılmıyorum, çünkü bu gerçekten sınıfa bir sorumluluk katıyor.
ssmith

3

Yazdığım bir makalede, singleton'un neden statik bir sınıftan çok daha iyi olduğu konusundaki görüşümü anlattım:

  1. Statik sınıf aslında kanonik sınıf değildir - işlevler ve değişkenler içeren bir ad alanı
  2. Statik sınıf kullanmak, nesne yönelimli programlama ilkelerini ihlal ettiği için iyi bir uygulama değildir.
  3. Statik sınıf, diğerleri için parametre olarak iletilemez
  4. Statik sınıf “tembel” başlatma için uygun değildir
  5. Statik sınıfın başlatılması ve kullanılması her zaman zor izlenir
  6. İş parçacığı yönetimini uygulamak zordur

İngilizce dilbilgisi için fırça, ama aksi takdirde, ilginç bir okuma :)
Noctis

3
  1. Singleton sınıfının nesnesini yaratabilir ve yönteme aktarabiliriz.

  2. Singleton sınıfı herhangi bir miras kısıtlaması getirmez.

  3. Statik bir sınıfın nesnelerini atamayız, ancak singleton sınıfını yapabiliriz.


Her zaman yalnızca bir tane varsa ve her zaman statik bir referansı varsa, tek bir yöntemi bir yönteme geçirmenin faydası nedir?
Aaron Franke

3

Statik sınıftan ayrılma

JDK'nın hem singleton hem de static örnekleri vardır, bir yandan java.lang.Mathstatik yöntemlerle son sınıf, diğer yandan java.lang.Runtimesingleton sınıfıdır.

Singleton'un Avantajları

  • Eğer durumu tekton modelden daha fazla korumanız gerekiyorsa statik sınıftan daha iyi bir seçimdir, çünkü statik sınıfta durumun korunması, özellikle eşzamanlı ortamlarda hatalara yol açar, bu da birden fazla iş parçacığı tarafından yeterli senkronizasyon paralel modifikasyonu olmadan yarış koşullarına yol açabilir.

  • Singleton sınıfı ağır bir nesne ise tembel olarak yüklenebilir, ancak statik sınıfın böyle avantajları yoktur ve her zaman hevesle yüklenir.

  • Singleton ile, bir temel sınıfı genişletmek, bir arayüz uygulamak ve farklı uygulamalar sağlamak için kalıtım ve polimorfizm kullanabilirsiniz.

  • Java'daki statik yöntemler geçersiz kılınamadığı için, esnek olmayanlığa yol açarlar. Öte yandan, singleton sınıfında tanımlanan yöntemleri genişleterek geçersiz kılabilirsiniz.

Statik sınıfın dezavantajları

  • Singleton için birim testi yazmak, statik sınıfa göre daha kolaydır, çünkü singleton beklendiğinde sahte nesneyi iletebilirsiniz.

Statik sınıfın avantajları

  • Statik sınıf, singleton'dan daha iyi performans sağlar, çünkü statik yöntemler derleme zamanında birleştirilir.

Her biri avantajları ve dezavantajları olan tekli modelin birkaç gerçekleştirilmesi vardır.

  • İstekli yükleme singletonu
  • Çift kontrollü kilitleme tekli
  • İsteğe bağlı başlatma deyimi
  • Enum Tabanlı Singleton

Ayrıntılı açıklama her biri çok ayrıntılı, bu yüzden sadece iyi bir makaleye bağlantı koydum - Singleton hakkında bilmek istediğiniz her şey


2

Bir arasında büyük bir fark vardır tek bir statik sınıf ve (statik veya global değişken olur bir sınıfın, bir tek örneğidir) Örneğin tek bir statik işaretçi öbek üzerinde sınıfının bir örneğine:

Uygulamanız çıktığında, statik sınıf örneğinin yıkıcısı çağrılır. Bu, statik örneği bir singleton olarak kullandıysanız, singletonunuz düzgün çalışmayı durdurdu demektir. Bu singletonu kullanan, örneğin farklı bir iş parçacığında hala kod çalışıyorsa, bu kodun çökmesi muhtemeldir.


1
Peki uygulama çıkarsa Singleton hala bellekte kalacak mı?
nanosoft

Sanırım mevcut iş parçanız uygulamadan çıktığında, değil mi? Uygulama çıkarsa, başka bir iş parçacığının ondan bir şey kullanmasının bir yolu yoktur.
Tom Brito

2

Kafamdaki fark, nesne yönelimli programlama (Singleton / Prototype) veya fonksiyonel programlama (Statik) uygulamak.

Odaklanmamız gereken şey, sonunda bir nesneyi tutmamız gerektiğinde, tekli model tarafından oluşturulan nesnelerin sayısına çok fazla odaklanıyoruz. Diğerlerinin söylediği gibi, genişletilebilir, parametre olarak geçirilebilir, ancak en önemlisi durum doludur.

Öte yandan, statik fonksiyonel programlama uygulamak için kullanılır. Statik üyeler bir sınıfa aittir. Vatansızlar.

Bu arada singleton statik sınıflar oluşturabileceğinizi biliyor muydunuz :)


Sınıfta her zaman statik bir referansı olduğu için, bir singletonu parametre olarak geçirmenin anlamı nedir?
Aaron Franke
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.