Apa itu singleton?
Singleton ialah salah satu corak reka bentuk paling mudah yang boleh digunakan pada kelas. Orang kadang-kadang berkata "kelas ini ialah singleton", bermakna kelas ini melaksanakan corak reka bentuk tunggal. Kadangkala perlu menulis kelas yang hanya satu objek boleh dibuat. Sebagai contoh, kelas yang bertanggungjawab untuk mengelog atau menyambung ke pangkalan data. Corak reka bentuk Singleton menerangkan bagaimana kita boleh mencapai tugas sedemikian. Singleton ialah corak reka bentuk yang melakukan dua perkara:-
Memberi jaminan bahawa kelas hanya akan mempunyai satu contoh kelas.
-
Menyediakan pusat akses global kepada contoh kelas ini.
-
Pembina persendirian. Mengehadkan keupayaan untuk mencipta objek kelas di luar kelas itu sendiri.
-
Kaedah statik awam yang mengembalikan contoh kelas. Kaedah ini dipanggil
getInstance
. Ini ialah titik akses global kepada contoh kelas.
Pilihan pelaksanaan
Corak reka bentuk tunggal digunakan dengan cara yang berbeza. Setiap pilihan adalah baik dan buruk dengan caranya sendiri. Di sini, seperti biasa: tidak ada yang ideal, tetapi anda perlu berusaha untuk mendapatkannya. Tetapi pertama sekali, mari kita tentukan apa yang baik dan apa yang buruk, dan apakah metrik yang mempengaruhi penilaian pelaksanaan corak reka bentuk. Mari kita mulakan dengan yang positif. Berikut adalah kriteria yang memberikan kelazatan dan daya tarikan pelaksanaan:-
Inisialisasi malas: apabila kelas dimuatkan semasa aplikasi berjalan tepat apabila ia diperlukan.
-
Kesederhanaan dan ketelusan kod: metrik, sudah tentu, adalah subjektif, tetapi penting.
-
Keselamatan benang: berfungsi dengan betul dalam persekitaran berbilang benang.
-
Prestasi tinggi dalam persekitaran berbilang benang: benang menyekat satu sama lain secara minimum atau tidak sama sekali apabila berkongsi sumber.
-
Inisialisasi bukan malas: apabila kelas dimuatkan apabila aplikasi bermula, tidak kira sama ada ia diperlukan atau tidak (paradoks, dalam dunia IT adalah lebih baik untuk menjadi malas)
-
Kerumitan dan kebolehbacaan kod yang lemah. Metrik juga subjektif. Kita akan beranggapan jika darah datang dari mata, pelaksanaannya begitu-begitu sahaja.
-
Kekurangan keselamatan benang. Dalam erti kata lain, "bahaya benang". Operasi yang salah dalam persekitaran berbilang benang.
-
Prestasi buruk dalam persekitaran berbilang benang: benang menyekat satu sama lain sepanjang masa atau selalunya apabila berkongsi sumber.
Kod
Kini kami bersedia untuk mempertimbangkan pelbagai pilihan pelaksanaan, menyenaraikan kebaikan dan keburukan:Penyelesaian Mudah
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Pelaksanaan paling mudah. Kelebihan:
-
Kesederhanaan dan ketelusan kod
-
Keselamatan benang
-
Prestasi tinggi dalam persekitaran berbilang benang
- Bukan pemula malas.
Permulaan Malas
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Tidak selamat benang
Aksesori Disegerakkan
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Keselamatan benang
-
Prestasi lemah dalam persekitaran berbilang benang
getInstance
disegerakkan, dan anda hanya boleh memasukkannya satu demi satu. Sebenarnya, kita tidak perlu menyegerakkan keseluruhan kaedah, tetapi hanya sebahagian daripadanya di mana kita memulakan objek kelas baharu. Tetapi kita tidak boleh hanya membungkus synchronized
bahagian yang bertanggungjawab untuk mencipta objek baharu dalam blok: ini tidak akan memberikan keselamatan benang. Ia lebih rumit sedikit. Kaedah penyegerakan yang betul diberikan di bawah:
Penguncian Disemak Dua Kali
public class Singleton {
private static Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Keselamatan benang
-
Prestasi tinggi dalam persekitaran berbilang benang
-
Tidak disokong pada versi Java yang lebih rendah daripada 1.5 (kata kunci yang tidak menentu telah ditetapkan dalam versi 1.5)
INSTANCE
mestilah sama ada final
, atau volatile
. Pelaksanaan terakhir yang akan kita bincangkan hari ini ialah Class Holder Singleton
.
Pemegang Kelas Singleton
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Keselamatan benang.
-
Prestasi tinggi dalam persekitaran berbilang benang.
-
Untuk operasi yang betul, adalah perlu untuk menjamin bahawa objek kelas
Singleton
dimulakan tanpa ralat. Jika tidak, panggilan kaedah pertamagetInstance
akan berakhir dengan ralatExceptionInInitializerError
, dan semua panggilan seterusnya akan gagalNoClassDefFoundError
.
Perlaksanaan | Inisialisasi malas | Keselamatan benang | Kelajuan multithreading | Bila nak guna? |
---|---|---|---|---|
Penyelesaian Mudah | - | + | Cepat | tidak pernah. Atau apabila permulaan malas tidak penting. Tetapi tidak pernah lebih baik. |
Permulaan Malas | + | - | Tidak berkaitan | Sentiasa apabila multithreading tidak diperlukan |
Aksesori Disegerakkan | + | + | Perlahan-lahan | tidak pernah. Atau apabila kelajuan kerja dengan multithreading tidak penting. Tetapi tidak pernah lebih baik |
Penguncian Disemak Dua Kali | + | + | Cepat | Dalam kes yang jarang berlaku apabila anda perlu mengendalikan pengecualian semasa membuat singleton. (apabila Singleton Pemegang Kelas tidak berkenaan) |
Pemegang Kelas Singleton | + | + | Cepat | Sentiasa apabila multithreading diperlukan dan terdapat jaminan bahawa objek kelas tunggal akan dicipta tanpa masalah. |
Kebaikan dan keburukan corak Singleton
Secara umum, singleton melakukan apa yang diharapkan daripadanya:-
Memberi jaminan bahawa kelas hanya akan mempunyai satu contoh kelas.
-
Menyediakan pusat akses global kepada contoh kelas ini.
-
Singleton melanggar SRP (Prinsip Tanggungjawab Tunggal) - kelas Singleton, sebagai tambahan kepada tanggungjawab segeranya, juga mengawal bilangan salinannya.
-
Kebergantungan kelas biasa atau kaedah pada singleton tidak kelihatan dalam kontrak awam kelas.
-
Pembolehubah global adalah buruk. Singleton akhirnya bertukar menjadi satu pembolehubah global yang besar.
-
Kehadiran singleton mengurangkan kebolehujian aplikasi secara umum dan kelas yang menggunakan singleton khususnya.
GO TO FULL VERSION