Perbedaan antara kelas statis dan pola tunggal?

1768

Apa perbedaan nyata (yaitu praktis) yang ada antara kelas statis dan pola tunggal?

Keduanya dapat dipanggil tanpa instantiation, keduanya hanya menyediakan satu "Instance" dan tidak satu pun dari mereka yang aman. Apakah ada perbedaan lain?

Jorge Córdoba
sumber
4
Bergantung pada implementasi bahasa dan pola penggunaan Anda, Singleton mungkin kurang efisien karena overhead memanggil getInstance()metode setiap kali Anda ingin menggunakannya (walaupun mungkin dalam kebanyakan kasus itu tidak masalah ).
terlalu banyak php
5
Sudah banyak jawaban. Ini sebenarnya adalah singletonobjek di mana staticmetode hanya berfungsi, entitas non-OO.
fastcodejava
4
Tergantung pada pelaksanaannya .. csharpindepth.com/Articles/General/Singleton.aspx
VJAI
4
Ada perbedaan ketika Anda ingin mengizinkan pihak ketiga untuk memasok implementasi kelas. Dalam hal ini Anda biasanya memerlukan pola Pabrik juga. Lihat agiletribe.wordpress.com/2013/10/08/...
AgilePro
IMO jawaban ini merangkum dengan sangat baik stackoverflow.com/questions/14097656/...
Dave

Jawaban:

1251

Apa yang membuat Anda mengatakan bahwa metode tunggal atau statis tidak aman? Biasanya keduanya harus diimplementasikan agar aman.

Perbedaan besar antara singleton dan sekelompok metode statis adalah bahwa lajang dapat mengimplementasikan antarmuka (atau berasal dari kelas dasar yang berguna, meskipun menurut pengalaman saya), sehingga Anda dapat mengedarkan singleton seolah-olah itu "hanyalah " penerapan.

Jon Skeet
sumber
29
Nah, jika Anda lebih suka, tidak ada yang secara inheren threadsafe, Anda harus membuat mereka menjadi threadsafe, keduanya, jadi tidak ada perbedaan di sana.
Jorge Córdoba
119
Bisakah Anda memberikan contoh sesuatu yang secara inheren threadsafe, selain tipe tidak berubah?
Jon Skeet
26
Kepada Skeet: Orang yang mengatakan bahwa singleton bukan threadsafe berarti bahwa singleton dibagikan di antara utas yang tidak perlu sepanjang waktu, sementara tumpukan objek dibagikan ketika Anda membutuhkannya, yang berarti Anda tidak perlu melakukan sinkronisasi yang tidak dibutuhkan.
45
@ Geek: Bayangkan singleton mengimplementasikan antarmuka Foo, dan Anda memiliki metode untuk mengambil Foosebagai parameter. Dengan pengaturan itu, penelepon dapat memilih untuk menggunakan singleton sebagai implementasinya - atau mereka dapat menggunakan implementasi yang berbeda. Metode ini dipisahkan dari singleton. Bandingkan dengan situasi di mana kelas hanya memiliki metode statis - setiap bagian dari kode yang ingin memanggil metode-metode tersebut secara erat digabungkan ke kelas, karena perlu menentukan kelas mana yang berisi metode statis.
Jon Skeet
10
@AmirBareket: Ini bukan singleton menurut pola desain singleton - jika kelas itu sendiri memungkinkan beberapa instance dibuat, itu bukan IMO singleton, terlepas dari apa yang dilakukan pabrik.
Jon Skeet
476

Jawaban yang benar adalah oleh Jon Skeet, di forum lain di sini .

Singleton memungkinkan akses ke instance tunggal yang dibuat - instance itu (atau lebih tepatnya, referensi ke instance itu) dapat dilewatkan sebagai parameter ke metode lain, dan diperlakukan sebagai objek normal.

Kelas statis hanya memungkinkan metode statis.

Kezzer
sumber
64
Namun, mengapa Anda melewatkan Singleton sebagai parameter, jika Anda dapat mengakses instance yang sama dari mana saja dengan memanggil metode static getInstance ()?
Henrique Ordine
23
@ HenriqueOrdine Jadi bisa masuk ke dalam kode yang ada dan menyediakan antarmuka?
6
@ HenriqueOrdine Mereka berbicara tentang kelas statis, bukan kelas dengan metode statis. Kelas statis tidak dapat dipakai. Namun demikian, jika Anda melewatkan sebuah instance dari kelas (non-statis) yang berisi metode statis, Anda tidak dapat memanggil metode statis pada sebuah instance.
Goran
3
Apa itu kelas statis? Setidaknya di Jawa, tidak ada yang seperti itu.
Henrique Ordine
16
@ Goran saya awalnya sangat bingung dengan kata-kata Anda. Anda berkata "Anda tidak dapat memanggil metode statis dengan instance". Saya membacanya sebagai "jika Anda memiliki referensi ke objek instantiated, Anda tidak dapat memanggil metode statis yang mungkin ada." Tentu saja itu salah. Setelah membacanya lagi beberapa kali saya pikir Anda maksudkan "dari dalam metode statis Anda tidak dapat mengakses objek non-statis di kelas" yang benar. Ingin mengklarifikasi bahwa bagi siapa pun yang baru mengenal konsep-konsep ini yang menemukan jawaban ini dan membaca komentar Anda.
Andrew Steitz
359
  1. Objek singleton disimpan dalam Heap , tetapi objek statis disimpan dalam stack .
  2. Kita dapat mengkloning (jika perancang tidak melarangnya) objek singleton, tetapi kita tidak dapat mengkloning objek kelas statis.
  3. Kelas singleton mengikuti OOP (prinsip berorientasi objek), kelas statis tidak.
  4. Kita dapat mengimplementasikan sebuah interfacedengan kelas Singleton, tetapi metode statis kelas (atau misalnya C # static class) tidak bisa.
Vadluri Sreenu
sumber
99
Pernyataan kedua salah. Kita tidak bisa mengkloning objek Singleton. Implementasi singleton harus menolak ini. Jika Anda benar-benar dapat mengkloning Singleton, itu bukan Singleton.
Alexander Yancharuk
19
Ini adalah jawaban yang tidak benar untuk Java: singleton maupun static tidak menggunakan stack.
AgilePro
72
# 1 tidak penting. # 2 menjelaskan implementasi yang rusak. # 3 benar-benar tidak dapat dibenarkan.
Casey
31
Bagaimana benda statis dapat disimpan dalam tumpukan? Frame stack baru dibuat ketika Anda memanggil suatu metode, ia menyimpan variabel lokal metode, bingkai stack ini dihapus ketika metode kembali, dan variabel-variabel lokal tersebut hilang. Tentu tumpukan cepat, tetapi tidak cocok untuk menyimpan objek statis.
mike_m
23
Saya tidak dapat memahami jumlah upvotes yang satu ini. 1) Mengapa Singleton harus disimpan dalam tumpukan? Dalam bahasa yang dikelola seperti C # atau data Java disimpan dalam tumpukan terkelola, kecuali untuk variabel / parameter metode lokal. 2) Jika Anda dapat mengkloningnya, maka itu bukan singleton yang diimplementasikan dengan benar. 3) Singleton dikenal sebagai anti-pola OOP; yaitu sesuatu yang harus Anda hindari jika memungkinkan. 4) Ini adalah satu-satunya hal yang benar.
Groo
152

Pola Singleton memiliki beberapa keunggulan dibandingkan kelas statis. Pertama, singleton dapat memperluas kelas dan mengimplementasikan antarmuka, sementara kelas statis tidak bisa (itu dapat memperluas kelas, tetapi tidak mewarisi anggota contoh mereka). Singleton dapat diinisialisasi dengan malas atau asinkron sementara kelas statis umumnya diinisialisasi ketika pertama kali dimuat, yang mengarah ke masalah potensi loader kelas. Namun, keuntungan yang paling penting adalah bahwa lajang dapat ditangani secara polimorfik tanpa memaksa penggunanya untuk berasumsi bahwa hanya ada satu contoh.

neil.johnson
sumber
10
+1 untuk poin pragmatis yang bagus. Pola Singleton terlalu sering digunakan, tetapi ada beberapa situasi yang cocok. Lihat juga: agiletribe.wordpress.com/2013/10/08/...
AgilePro
3
Anda benar tentang keuntungan menjadi polimorfik. Ini adalah poin terpenting
Ahmad
Kelas statis bersarang dapat mengimplementasikan antarmuka. Coba kodekan, akan berhasil. Saya dapat mengkompilasi kode tanpa kesalahan.
nanosoft
75

statickelas bukan untuk apa pun yang membutuhkan negara. Ini berguna untuk menyatukan banyak fungsi yaitu Math(atau Utilsdalam proyek). Jadi nama kelas hanya memberi kita petunjuk di mana kita dapat menemukan fungsi dan tidak lebih.

Singletonadalah pola favorit saya dan saya menggunakannya untuk mengelola sesuatu pada satu titik. Ini lebih fleksibel daripada statickelas dan dapat mempertahankan keadaan itu. Itu dapat mengimplementasikan antarmuka, mewarisi dari kelas lain dan memungkinkan warisan.

Aturan saya untuk memilih antara staticdan singleton:

Jika ada banyak fungsi yang harus disimpan bersama, maka itu staticadalah pilihan. Hal lain yang membutuhkan akses tunggal ke beberapa sumber daya, dapat diimplementasikan sebagai singleton.

Xaqron
sumber
16
Mengapa kelas statis tidak melakukan apa pun yang perlu menyelamatkan negara?
Dipotong
12
@Trisped: Anda tidak memiliki kontrol yang akurat atas inisialisasi atau finalisasi.
Xaqron
7
Anda kehilangan saya di "Singleton adalah pola favorit saya". Singleton adalah sudut yang begitu tajam sehingga harus dianggap sebagai anti-pola dan juga pola. Kelas dapat memiliki keadaan statis, itu juga akses tunggal, jika keadaan statis apa pun lebih "akses tunggal" daripada lajang karena sebagian besar implementasi tunggal yaitu rusak. Anda dapat mengkloning singleton, sementara statis diberkati oleh definisi menjadi unik.
PoweredByRice
1
Apa artinya mempertahankan status? Apa itu negara?
Kyle Delaney
2
@KyleDelaney: Cukup Stateadalah kombinasi dari berbagai properti dari suatu objek yang biasanya berubah seiring waktu. Anda dapat Google untuk definisi formal.
Xaqron
65

Kelas Statis: -

  1. Anda tidak dapat membuat turunan dari kelas statis.

  2. Dimuat secara otomatis oleh .NET Framework common language runtime (CLR) ketika program atau namespace yang mengandung kelas dimuat.

  3. Kelas Statis tidak dapat memiliki konstruktor.

  4. Kami tidak dapat meneruskan kelas statis ke metode.

  5. Kami tidak dapat mewarisi kelas Statis ke kelas Statis lain di C #.

  6. Kelas yang memiliki semua metode statis.

  7. Performa yang lebih baik (metode statis terikat pada waktu kompilasi)

Singleton: -

  1. Anda dapat membuat satu instance objek dan menggunakannya kembali.

  2. Singleton instance dibuat untuk pertama kalinya ketika pengguna meminta.

  3. Kelas singleton dapat memiliki konstruktor.

  4. Anda bisa membuat objek kelas singleton dan meneruskannya ke metode.

  5. Kelas singleton tidak menyebutkan batasan Warisan.

  6. Kita dapat membuang objek dari kelas singleton tetapi tidak dari kelas statis.

  7. Metode dapat diganti.

  8. Dapat dimuat malas ketika perlu (kelas statis selalu dimuat).

  9. Kami dapat mengimplementasikan antarmuka (kelas statis tidak dapat mengimplementasikan antarmuka).

RajeshVerma
sumber
13
Kelas-kelas statis memang memiliki konstruktor: msdn.microsoft.com/en-us/library/k9x6w0hc.aspx
Tomer Arazy
2
Ya, statis dapat memiliki konstruktor yang internal ke kelas itu. Ini dipanggil ketika metode statis di kelas dipanggil.
rahulmr
Untuk singleton pada waktu kompilasi, ia disimpan dalam memori HEAP tetapi jika ia dipakai setelah itu disimpan di STACK?
Luminous_Dev
@ Luminous_Dev Tidak. Setiap instance tunggal adalah instance objek pada akhir hari. Ini akan disimpan di heap tanpa ragu.
RBT
1
@rahulmr Perbedaan penting: konstruktor juga dipanggil sebelum turunan pertama (AKA saja) dibuat.
CoolOppo
53

Kelas statis adalah kelas yang hanya memiliki metode statis, yang kata yang lebih baik adalah "fungsi". Gaya desain yang terkandung dalam kelas statis adalah murni prosedural.

Singleton, di sisi lain, adalah pola khusus untuk desain OO. Ini adalah turunan dari sebuah objek (dengan semua kemungkinan yang melekat di dalamnya, seperti polimorfisme), dengan prosedur penciptaan yang memastikan bahwa hanya ada satu instance dari peran tertentu itu selama seumur hidupnya.

Morendil
sumber
1
polimorfisme tidak ikut bermain dengan lajang sama sekali
32
Jadi, menurut Anda. Saya berpikir secara berbeda. ;) Misalnya, bayangkan sebuah pabrik tunggal yang mengembalikan antarmuka. Anda tahu Anda mendapatkan ISingleton (dan itu sama untuk selamanya) tetapi belum tentu implementasi yang mana.
Morendil
Kelas statis bersarang dapat memiliki metode instan juga, itu tidak terbatas hanya memiliki metode statis .. Kode itu dan Anda dapat melihat.
nanosoft
Dalam bahasa dengan model objek yang lebih bagus (misalnya Ruby), kelas juga objek. Aspek "murni prosedural" dari kelas statis adalah pembatasan sewenang-wenang yang diberlakukan oleh bahasa.
Maks.
36

Dalam pola singleton Anda bisa membuat singleton sebagai turunan dari tipe turunan, Anda tidak bisa melakukannya dengan kelas statis.

Contoh cepat:

if( useD3D )
    IRenderer::instance = new D3DRenderer
else
    IRenderer::instance = new OpenGLRenderer
Don Neufeld
sumber
39
Ini bukan pola tunggal, lebih mirip pabrik bagi saya.
vava
10
Tidak juga, perbedaan mendasar antara keduanya adalah bahwa Singleton akan "cache" objek tunggal dan terus mengembalikan (referensi ke) objek yang sama. Pola Pabrik akan membuat instance baru.
Mystic
12
Maka itu proxy tunggal :)
vava
3
Hmm, saya tahu jenis Singleton ini sebagai MonoState.
Huppie
Contohnya adalah pola pabrik
Rajavel D
26

Untuk memperluas Jawaban Jon Skeet

Perbedaan besar antara singleton dan sekelompok metode statis adalah bahwa lajang dapat mengimplementasikan antarmuka (atau berasal dari kelas dasar yang berguna, meskipun itu IME yang kurang umum), sehingga Anda dapat mengedarkan singleton seolah-olah itu adalah implementasi "sekadar yang lain".

Lajang lebih mudah digunakan ketika unit menguji sebuah kelas. Di mana pun Anda melewati lajang sebagai parameter (konstruktor, setter atau metode), Anda dapat mengganti versi singleton yang diejek atau di-stub.

Mike Rylander
sumber
Saya tidak berpikir Anda bisa langsung mengejek seorang pria. Tidakkah Anda harus mendeklarasikan antarmuka yang diimplementasikan oleh singleton dan mock class?
Ellen Spertus
@ Espertus Mengapa kamu tidak bisa mengejek singleton Anda? Contoh menggunakan mockito MySingleton mockOfMySingleton = mock(MySingleton.class).
Mike Rylander
Anda benar, Anda dapat mengejeknya dengan alat seperti mockito yang menggunakan refleksi. Maksud saya, Anda tidak dapat mengejeknya secara langsung dengan mensubklasifikasikan dan mengganti metode-metodenya.
Ellen Spertus
@ Espertus Kenapa tidak? Saat Anda membuat instance objek yang Anda uji, Anda dapat mengganti implementasi subclass dari singleton Anda di mana pun Anda akan menggunakan yang asli. Contoh:new ClazzToTest(mockSingleton);
Mike Rylander
Saya belum pernah menggunakan Mockito, tetapi bagaimana Anda bisa mensubkelas kelas yang memiliki konstruktor pribadi, yang merupakan kasus untuk lajang, kecuali dengan menggunakan refleksi? Diskusi terkait: stackoverflow.com/questions/2302179/mocking-a-singleton-class stackoverflow.com/questions/15939023/…
Ellen Spertus
23

Inilah artikel yang bagus: http://javarevisited.blogspot.com.au/2013/03/difference-between-singleton-pattern-vs-static-class-java.html

Kelas statis

  • kelas yang memiliki semua metode statis .
  • kinerja yang lebih baik (metode statis terikat pada waktu kompilasi)
  • tidak dapat menimpa metode, tetapi dapat menggunakan metode bersembunyi. ( Apa metode bersembunyi di Jawa? Bahkan penjelasan JavaDoc membingungkan )

    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

Singkatnya, saya hanya akan menggunakan kelas statis untuk memegang metode util, dan menggunakan Singleton untuk yang lainnya.


Suntingan

JackDev
sumber
4
Saya tidak tahu tentang java, tetapi dalam. Net, dua poin terakhir Anda salah. Kelas statis dapat mereferensikan properies statis dan bidang, sehingga pada kondisi mereka sama. Dan mereka malas dimuat - konstruktor statis dijalankan ketika: 1) Sebuah instance dari kelas dibuat. 2) Salah satu anggota statis kelas direferensikan. 1 tidak berlaku, yang meninggalkan 2. Jadi, kelas statis tidak dimuat sampai pertama kali digunakan.
jmoreno
1
Untuk kelas statis, meskipun Anda tidak bisa mengganti metode statis, Anda bisa menyembunyikan metode statis dari induknya.
Max Peng
jika Animal animal = new Cat();kemudian animal.foo();apa yang terjadi?
Luminous_Dev
@jmoreno kelas statis tidak dimuat sampai digunakan pertama kali? Saya percaya itu disimpan dalam memori tumpukan pada waktu kompilasi. Dan itu langsung diakses .. bukan?
Luminous_Dev
@ Luminous_Dev: setidaknya untuk .net, kelas statis memiliki konstruktor yang berjalan saat pertama kali diakses, jadi tidak ada itu tidak dapat diakses secara instan. Konstruktor statis dapat secara teori mengambil jumlah waktu yang tidak terbatas. Di mana (atau kelas lain disimpan) adalah detail implementasi, itu tidak benar-benar relevan dengan pertanyaan ini.
jmoreno
22

Keuntungan lain dari singleton adalah ia dapat dengan mudah diserialisasi, yang mungkin diperlukan jika Anda perlu menyimpan statusnya ke disk, atau mengirimnya ke suatu tempat dari jarak jauh.

Alex
sumber
19

Saya bukan ahli teori OO yang hebat, tetapi dari apa yang saya tahu, saya pikir satu-satunya fitur OO yang tidak dimiliki kelas statis dibandingkan dengan Singletons adalah polimorfisme. Tetapi jika Anda tidak membutuhkannya, dengan kelas statis tentu saja Anda dapat memiliki warisan (tidak yakin tentang implementasi antarmuka) dan enkapsulasi data dan fungsi.

Komentar Morendil, "Gaya desain yang terkandung dalam kelas statis adalah murni prosedural" Saya mungkin salah, tapi saya tidak setuju. Dalam metode statis Anda dapat mengakses anggota statis, yang akan persis sama dengan metode tunggal yang mengakses anggota contoh tunggal mereka.

sunting:
Saya sebenarnya berpikir sekarang bahwa perbedaan lain adalah bahwa kelas Static adalah instantiated saat program mulai * dan kehidupan sepanjang rentang kehidupan seluruh program, sementara tunggal secara eksplisit dipakai di beberapa titik dan bisa hancur juga.

* atau mungkin dipakai pada penggunaan pertama, tergantung pada bahasa, saya pikir.

Petruza
sumber
15
Ya, semua orang tampaknya mengabaikan fakta bahwa kelas dengan metode statis juga dapat memiliki bidang statis pribadi yang masih dapat digunakan untuk mempertahankan status (dan mengekspos beberapa di antaranya ke kode klien melalui seter / pengambil statis publik).
user289463
17

Untuk mengilustrasikan poin Jon, apa yang ditunjukkan di bawah ini tidak dapat dilakukan jika Logger adalah kelas statis. Kelas SomeClassmengharapkan instance dariILogger implementasi untuk diteruskan ke konstruktornya.

Kelas singleton penting untuk injeksi ketergantungan menjadi mungkin.

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();
    }
}
developer747
sumber
13

Yah seorang singleton hanyalah kelas normal yang IS dipakai tetapi hanya sekali dan tidak langsung dari kode klien. Kelas statis tidak dipakai. Sejauh yang saya tahu metode statis (kelas statis harus memiliki metode statis) lebih cepat daripada non-statis.

Sunting:
Uraian aturan kinerja FxCop: "Metode yang tidak mengakses data instance atau metode instance panggilan dapat ditandai sebagai statis (Dibagikan dalam VB). Setelah melakukannya, kompiler akan memancarkan situs panggilan non-virtual kepada anggota ini yang akan mencegah periksa saat runtime untuk setiap panggilan yang mengasuransikan pointer objek saat ini adalah non-null. Ini dapat menghasilkan peningkatan kinerja yang terukur untuk kode yang sensitif terhadap kinerja. Dalam beberapa kasus, kegagalan untuk mengakses instance objek saat ini merupakan masalah kebenaran. "
Saya sebenarnya tidak tahu apakah ini berlaku juga untuk metode statis di kelas statis.

agnieszka
sumber
11

Singleton's instantiated, hanya saja hanya ada satu instantiated, maka single di Singleton.

Kelas statis tidak dapat dipakai oleh apa pun selain dirinya sendiri.

Kezzer
sumber
Kelas statis bisa sangat dipakai di java. Baca docs.oracle.com/javase/tutorial/java/javaOO/nested.html.
Rujuk juga
8

Perbedaan utama adalah:

  • Singleton memiliki instance / objek sedangkan kelas statis adalah sekelompok metode statis
  • Singleton dapat diperluas misalnya melalui antarmuka sementara kelas statis tidak bisa.
  • Singleton dapat diwarisi yang mendukung prinsip buka / tutup dalam prinsip SOLID di sisi lain, kelas statis tidak dapat diwarisi dan kita perlu membuat perubahan dalam dirinya sendiri.
  • Objek singleton dapat diteruskan ke metode sementara kelas statis karena tidak memiliki instance tidak dapat diteruskan sebagai parameter
Faran Shabbir
sumber
7

Singleton adalah pendekatan yang lebih baik dari perspektif pengujian. Tidak seperti kelas statis, singleton dapat mengimplementasikan antarmuka dan Anda dapat menggunakan contoh tiruan dan menyuntikkan mereka.

Dalam contoh di bawah ini saya akan menggambarkan ini. Misalkan Anda memiliki metode isGoodPrice () yang menggunakan metode getPrice () dan Anda menerapkan getPrice () sebagai metode dalam singleton.

singleton yang menyediakan fungsionalitas getPrice:

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;
    }
}

Penggunaan getPrice:

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();
    }

Implementasi Final Singleton:

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;
    }

kelas tes:

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);

    }

}

Jika kita mengambil alternatif menggunakan metode statis untuk mengimplementasikan getPrice (), sulit untuk mengejek getPrice (). Anda dapat mengejek statis dengan mengejek listrik, namun tidak semua produk dapat menggunakannya.

Amir Bareket
sumber
1
Itu sekarang bukan utas yang aman, dan umumnya tidak menyenangkan dalam hal bagaimana Anda mengakses implementasi antarmuka. Tentu, memiliki antarmuka bagus untuk testabilitas - tapi lalu mengapa repot-repot dengan singleton? Hanya menghindari memiliki lajang sama sekali; minta satu kelas mengimplementasikannya untuk tujuan produksi, satu implementasi untuk tujuan pengujian, dan menyuntikkan instance yang tepat tergantung pada apa yang Anda lakukan. Tidak perlu memasangkan singleton ke peneleponnya sama sekali.
Jon Skeet
Terima kasih untuk umpan baliknya. sangat mudah untuk membuatnya aman. selain itu, saya menggunakan singleton untuk tujuan caching.
Amir Bareket
1
Ya, meskipun dengan overhead yang tidak ada gunanya. Sekali lagi, hanya lebih sederhana untuk tidak menggunakan singleton.
Jon Skeet
6

Saya setuju dengan definisi ini:

Kata " tunggal " berarti objek tunggal di seluruh siklus hidup aplikasi, sehingga cakupannya berada pada level aplikasi.

The statis tidak memiliki Object pointer, sehingga lingkup adalah pada tingkat App Domain.

Selain itu keduanya harus diimplementasikan agar aman.

Anda dapat menemukan perbedaan menarik lainnya tentang: Singleton Pattern Versus Static Class

Alessandro Ornano
sumber
5

Satu perbedaan penting adalah instantiasi berbeda yang datang dengan Singletons.

Dengan kelas statis, itu akan dibuat oleh CLR dan kami belum mengontrolnya. dengan lajang, objek akan dipakai pada instance pertama yang mencoba diakses.

Eranga Dissanayaka
sumber
4

Dalam banyak kasus, keduanya tidak memiliki perbedaan praktis, terutama jika instance tunggal tidak pernah berubah atau berubah sangat lambat misalnya memegang konfigurasi.

Saya akan mengatakan perbedaan terbesar adalah singleton masih Java Bean normal dibandingkan dengan kelas Java khusus statis. Dan karena ini, seorang lajang diterima dalam lebih banyak situasi; itu sebenarnya adalah strategi instantiation Spring Framework default. Konsumen mungkin atau mungkin tidak tahu itu singleton yang diedarkan, itu hanya memperlakukannya seperti kacang Jawa biasa. Jika perubahan kebutuhan dan singleton perlu menjadi prototipe, seperti yang sering kita lihat di Spring, itu dapat dilakukan dengan mulus tanpa garis kode berubah ke konsumen.

Orang lain telah menyebutkan sebelumnya bahwa kelas statis harus murni prosedural misalnya java.lang.Math. Dalam pikiranku, kelas seperti itu seharusnya tidak pernah diedarkan dan mereka tidak boleh memiliki apa pun selain final statis sebagai atribut. Untuk yang lainnya, gunakan singleton karena jauh lebih fleksibel dan lebih mudah dirawat.

Chris
sumber
4

Kami memiliki kerangka kerja DB kami yang membuat koneksi ke Back end. Untuk Menghindari Dirty membaca di beberapa pengguna, kami telah menggunakan pola tunggal untuk memastikan kami memiliki satu instance tersedia pada setiap titik waktu.

Di c # kelas statis tidak dapat mengimplementasikan antarmuka. Ketika kelas instance tunggal perlu mengimplementasikan antarmuka untuk kontrak bisnis atau tujuan IoC, ini adalah tempat saya menggunakan pola Singleton tanpa kelas statis

Singleton menyediakan cara untuk mempertahankan status dalam skenario stateless

Semoga itu bisa membantu Anda ..

RK_Muddala
sumber
3
  1. Pemuatan Malas
  2. Dukungan antarmuka, sehingga implementasi yang terpisah dapat disediakan
  3. Kemampuan untuk mengembalikan tipe turunan (sebagai kombinasi dari lazyloading dan implementasi antarmuka)
Tilak
sumber
Kelas statis bersarang dapat sangat mengimplementasikan antarmuka dalam java. Poin kedua Anda salah.
nanosoft
3

Sebuah. Serialisasi - Anggota statis adalah anggota kelas dan karenanya tidak dapat diserialisasi.

b. Meskipun kami telah menjadikan konstruktor sebagai pribadi, variabel anggota statis masih akan dibawa ke subkelas.

c. Kami tidak dapat melakukan inisialisasi malas karena semuanya akan dimuat pada pemuatan kelas saja.

Vivek Vermani
sumber
3

Dari perspektif klien, perilaku statis diketahui oleh klien tetapi perilaku Singleton dapat diselesaikan tersembunyi dari klien. Klien mungkin tidak pernah tahu bahwa hanya ada satu instance yang dia mainkan berulang kali.

Arpit Khandelwal
sumber
3

Saya membaca yang berikut ini dan berpikir itu masuk akal juga:

Merawat Bisnis

Ingat, salah satu aturan OO yang paling penting adalah bahwa objek bertanggung jawab atas dirinya sendiri. Ini berarti bahwa masalah mengenai siklus hidup suatu kelas harus ditangani di kelas, tidak didelegasikan ke konstruksi bahasa seperti statis, dan sebagainya.

dari buku Objected-Oriented Thought Process 4th Ed.

nonopolaritas
sumber
Saya tidak setuju, karena ini benar-benar hanya menambah tanggung jawab pada kelas, yang (dengan anggapan itu melakukan apa saja) berarti sekarang melanggar Prinsip Tanggung Jawab Tunggal.
ssmith
3

Dalam sebuah artikel yang saya tulis saya telah menjelaskan sudut pandang saya tentang mengapa singleton jauh lebih baik daripada kelas statis:

  1. Kelas statis sebenarnya bukan kelas kanonik - ini adalah namespace dengan fungsi dan variabel
  2. Menggunakan kelas statis bukanlah praktik yang baik karena melanggar prinsip-prinsip pemrograman berorientasi objek
  3. Kelas statis tidak dapat diteruskan sebagai parameter untuk yang lain
  4. Kelas statis tidak cocok untuk inisialisasi "malas"
  5. Inisialisasi dan penggunaan kelas statis selalu sulit dilacak
  6. Menerapkan manajemen utas sulit
Paul R
sumber
Saya akan memolesnya untuk tata bahasa Inggris, tetapi jika tidak, ini adalah bacaan yang menarik :)
Noctis
3
  1. Kita dapat membuat objek kelas singleton dan meneruskannya ke metode.

  2. Kelas singleton tidak membatasi waris.

  3. Kita tidak bisa membuang objek dari kelas statis tetapi bisa kelas singleton.

Sanjay Dwivedi
sumber
Apa gunanya memasukkan singleton ke dalam metode jika hanya ada satu dan yang selalu memiliki referensi statis?
Aaron Franke
3

Perbedaan dari kelas statis

JDK memiliki contoh singleton dan static, di satu sisi java.lang.Mathadalah kelas final dengan metode statis, di sisi lain java.lang.Runtimeadalah kelas singleton.

Keuntungan dari singleton

  • Jika kebutuhan Anda untuk mempertahankan status daripada pola tunggal adalah pilihan yang lebih baik daripada kelas statis, karena mempertahankan status di kelas statis mengarah ke bug, terutama di lingkungan bersamaan, yang dapat menyebabkan kondisi balapan tanpa sinkronisasi paralel modifikasi yang memadai oleh beberapa utas.

  • Kelas singleton dapat dimuat dengan malas jika merupakan objek yang berat, tetapi kelas statis tidak memiliki kelebihan seperti itu dan selalu bersemangat dimuat.

  • Dengan singleton, Anda dapat menggunakan pewarisan dan polimorfisme untuk memperluas kelas dasar, mengimplementasikan antarmuka dan menyediakan implementasi yang berbeda.

  • Karena metode statis di Java tidak dapat ditimpa, metode ini menyebabkan tidak fleksibel. Di sisi lain, Anda bisa mengganti metode yang didefinisikan dalam kelas singleton dengan memperluasnya.

Kekurangan dari kelas statis

  • Lebih mudah untuk menulis unit test untuk singleton daripada kelas statis, karena Anda dapat lulus objek tiruan setiap kali singleton diharapkan.

Keuntungan dari kelas statis

  • Kelas statis memberikan kinerja yang lebih baik daripada singleton, karena metode statis terikat pada waktu kompilasi.

Ada beberapa realisasi pola tunggal masing-masing dengan kelebihan dan kekurangan.

  • Ingin memuat singleton
  • Penguncian tunggal singleton
  • Idiom inisialisasi sesuai permintaan
  • Singleton berbasis enum

Deskripsi mendetail masing-masing dari mereka terlalu bertele-tele jadi saya hanya menaruh tautan ke artikel yang bagus - Yang ingin Anda ketahui tentang Singleton

Oleg Poltoratskii
sumber
2

Ada perbedaan besar antara instance kelas statis tunggal (yaitu, satu instance kelas, yang merupakan variabel statis atau global) dan satu pointer statis tunggal ke instance kelas di heap:

Ketika aplikasi Anda keluar, destruktor instance kelas statis akan dipanggil. Itu berarti jika Anda menggunakan contoh statis itu sebagai singleton, singleton Anda berhenti bekerja dengan benar. Jika masih ada kode yang berjalan yang menggunakan singleton itu, misalnya di utas yang berbeda, kode itu kemungkinan besar akan mogok.

gnasher729
sumber
1
Jadi jika aplikasi keluar, apakah Singleton akan tetap berada dalam memori?
nanosoft
Saya pikir maksud Anda ketika utas Anda saat ini keluar, bukan aplikasi, kan? Jika aplikasi keluar, tidak ada utas lain untuk menggunakan apa pun darinya.
Tom Brito
2

Perbedaan di kepala saya adalah menerapkan pemrograman berorientasi objek (Singleton / Prototipe) atau pemrograman fungsional (Statis).

Kita terlalu fokus pada jumlah objek yang diciptakan oleh pola singleton ketika apa yang harus kita fokuskan adalah pada akhirnya kita memegang suatu objek. Seperti yang telah dikatakan orang lain, ini dapat diperluas, diteruskan sebagai parameter tetapi yang paling penting adalah keadaan penuh.

Di sisi lain statis digunakan untuk mengimplementasikan pemrograman fungsional. Anggota statis milik kelas. Mereka tanpa kewarganegaraan.

Omong-omong, apakah Anda tahu bahwa Anda dapat membuat kelas statis tunggal :)

Atif Karbelkar
sumber
Apa gunanya meloloskan singleton sebagai parameter karena selalu memiliki referensi statis di kelas?
Aaron Franke