Apa itu singleton di Jawa?
Singleton adalah salah satu pola desain tingkat kelas yang paling sederhana. Kadang-kadang orang mengatakan "kelas ini tunggal", yang berarti bahwa kelas mengimplementasikan pola desain tunggal. Kadang-kadang perlu untuk menulis sebuah kelas di mana kita membatasi instantiasi ke objek tunggal. Misalnya, kelas yang bertanggung jawab untuk masuk atau menghubungkan ke database. Pola desain singleton menjelaskan bagaimana kita bisa mencapainya. Singleton adalah pola desain yang melakukan dua hal:-
Ini menjamin bahwa hanya akan ada satu instance kelas.
-
Ini memberikan satu titik akses global ke instans itu.
-
Seorang konstruktor pribadi. Ini membatasi kemampuan untuk membuat objek kelas di luar kelas itu sendiri.
-
Metode statis publik yang mengembalikan instance kelas. Metode ini disebut getInstance . Ini adalah titik akses global ke instance kelas.
Opsi implementasi
Pola desain singleton diterapkan dalam berbagai cara. Setiap opsi baik dan buruk dengan caranya sendiri. Seperti biasa, tidak ada pilihan yang sempurna di sini, tetapi kita harus berusaha untuk itu. Pertama-tama, mari kita putuskan apa yang baik dan buruk, dan metrik apa yang memengaruhi cara kita menilai berbagai implementasi pola desain. Mari kita mulai dengan yang baik. Berikut adalah faktor-faktor yang membuat implementasi lebih menarik dan menarik:-
Inisialisasi malas: instance tidak dibuat sampai dibutuhkan.
-
Kode sederhana dan transparan: metrik ini, tentu saja, subjektif, tetapi penting.
-
Keamanan utas: operasi yang benar di lingkungan multi-utas.
-
Performa tinggi di lingkungan multi-utas: sedikit atau tidak ada pemblokiran utas saat berbagi sumber daya.
-
Tidak ada inisialisasi malas: ketika kelas dimuat saat aplikasi dimulai, terlepas dari apakah itu diperlukan atau tidak (paradoksnya, di dunia IT lebih baik malas)
-
Kode yang rumit dan sulit dibaca. Metrik ini juga subjektif. Jika mata Anda mulai berdarah, kami menganggap penerapannya bukan yang terbaik.
-
Kurangnya keamanan benang. Dengan kata lain, "benang bahaya". Operasi yang salah di lingkungan multi-utas.
-
Performa buruk di lingkungan multi-utas: utas saling memblokir setiap saat atau sering saat berbagi sumber daya.
Kode
Sekarang kami siap untuk mempertimbangkan berbagai opsi implementasi dan menunjukkan pro dan kontra:Sederhana
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Implementasi paling sederhana. Kelebihan:
-
Kode sederhana dan transparan
-
Keamanan benang
-
Performa tinggi di lingkungan multi-utas
- Tidak ada inisialisasi malas.
Inisialisasi malas
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Tidak aman benang
Akses tersinkronisasi
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Kelebihan:
-
Inisialisasi malas.
-
Keamanan benang
-
Performa multithread yang buruk
Penguncian diperiksa ulang
public class Singleton {
private static final 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.
-
Keamanan benang
-
Performa tinggi di lingkungan multi-utas
-
Tidak didukung di versi Java sebelumnya di bawah 1.5 (penggunaan kata kunci volatil diperbaiki sejak versi 1.5)
Pemegang kelas
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.
-
Keamanan benang.
-
Performa tinggi di lingkungan multi-utas.
-
Operasi yang benar memerlukan jaminan bahwa objek tunggal diinisialisasi tanpa kesalahan. Jika tidak, panggilan pertama ke metode getInstance akan menghasilkan ExceptionInInitializerError , dan semua panggilan selanjutnya akan menghasilkan NoClassDefFoundError .
Penerapan | Inisialisasi malas | Keamanan benang | Performa multithread | Kapan harus digunakan? |
---|---|---|---|---|
Sederhana | - | + | Cepat | Tidak pernah. Atau mungkin saat inisialisasi malas tidak penting. Tapi tidak akan pernah lebih baik. |
Inisialisasi malas | + | - | Tak dapat diterapkan | Selalu saat multithreading tidak diperlukan |
Akses tersinkronisasi | + | + | Lambat | Tidak pernah. Atau mungkin saat kinerja multithreaded tidak menjadi masalah. Tapi tidak akan pernah lebih baik. |
Penguncian diperiksa ulang | + | + | Cepat | Dalam kasus yang jarang terjadi ketika Anda perlu menangani pengecualian saat membuat singleton (ketika singleton pemegang kelas tidak berlaku) |
Pemegang kelas | + | + | Cepat | Setiap kali multithreading diperlukan dan ada jaminan bahwa objek tunggal akan dibuat tanpa masalah. |
Pro dan kontra dari pola singleton
Secara umum, singleton melakukan apa yang diharapkan darinya:-
Ini menjamin bahwa hanya akan ada satu instance kelas.
-
Ini memberikan satu titik akses global ke instans itu.
-
Singleton melanggar prinsip tanggung jawab tunggal: selain tugas langsungnya, kelas singleton juga mengontrol jumlah instance.
-
Ketergantungan kelas biasa pada singleton tidak terlihat dalam kontrak publik kelas.
-
Variabel global buruk. Pada akhirnya, singleton berubah menjadi variabel global yang lumayan.
-
Kehadiran singleton mengurangi testabilitas aplikasi secara keseluruhan dan kelas yang menggunakan singleton pada khususnya.
GO TO FULL VERSION