Anda baru-baru ini mempelajari singleton design pattern , bagaimana menerapkannya di Java, dan untuk apa. Tetapi bagaimana jika saya memberi tahu Anda bahwa Java hadir dengan singletonnya sendiri di luar kotak? Penasaran? Lalu mari selami.

Anda mungkin sudah tahu tentang kelas Enum . Ini memiliki fitur khusus yang harus Anda ketahui. Secara khusus, Enum mengimplementasikan pola desain tunggal. Pilihan ini hampir sama dengan pendekatan tunggal yang melibatkan bidang publik .

Singleton sebagai enum:


public enum Device {   
    PRINTER	
} 
    

Singleton sebagai variabel publik:


public class Printer {   
    public static final Printer PRINTER = new Printer();   
    private Printer() {
    }
//…
}
    

Pendekatan enum lebih kompak daripada pendekatan bidang publik, karena kita tidak perlu menulis implementasi kita sendiri . Yang terpenting, enum tidak memiliki masalah dengan serialisasi.

Serialisasi enum bekerja secara berbeda dari objek biasa: hanya nilai nama enum yang diserialisasi. Selama deserialization, metode ini digunakan dengan nama deserialized untuk mendapatkan sebuah instance. Selain itu, enum dapat melindungi Anda dari serangan refleksi .

Anda akan belajar lebih banyak tentang refleksi dalam pelajaran di modul kedua, di mana kita akan menjelajahi API Refleksi .

Java melarang pembuatan enum —sebuah batasan yang dimasukkan ke dalam penerapan metode newInstance kelas Konstruktor , yang sering dipanggil saat membuat objek melalui refleksi.

Kutipan kode dari Constructor.newInstance . Digunakan untuk membuat enum :


if ((clazz.getModifiers() & Modifier.ENUM) != 0)
    throw new IllegalArgumentException("Cannot reflectively create enum objects");
    

Kerugian menggunakan enum untuk membuat singleton meliputi:

  • Kurangnya inisialisasi malas, karena objek segera dibuat dan inisialisasi tidak dapat ditunda.

  • Kelas lain tidak dapat diperpanjang. Artinya, jika Anda perlu mewarisi kelas lain, tidak akan berhasil menggunakan enum sebagai singleton. Dalam kasus seperti itu, kita perlu beralih ke opsi implementasi lain yang sudah kita kenal: metode statis atau variabel publik.

  • Saat menggunakan enum sebagai singleton, Anda hanya dapat menggunakan satu bidang enum .


public enum Device extends Electricity { 
    PRINTER 
}
    

Kode ini akan memberi kita kesalahan kompilasi:

Tidak ada klausa perluasan yang diizinkan untuk enum

Tetapi jika kita perlu mengimplementasikan interface, tidak ada masalah, karena enum dapat mengimplementasikan interface:


public enum Device implements Electricity { 
    PRINTER 
}
    

Jika Anda tidak perlu menggunakan pewarisan, sebaiknya terapkan pola singleton melalui enum . Kami tidak sendirian dalam merekomendasikan ini — Joshua Bloch sendiri juga melakukannya .

Pendekatan implementasi ini memberi Anda kenyamanan, kekompakan, serialisasi di luar kotak, perlindungan dari serangan refleksi, dan keunikan — semua yang dibutuhkan oleh singleton yang baik!