Anda baru-baru ini menyelidiki corak reka bentuk tunggal , cara melaksanakannya dalam Java dan untuk kegunaannya. Tetapi bagaimana jika saya memberitahu anda bahawa Java datang dengan singleton sendiri di luar kotak? Tertarik? Kemudian mari kita menyelam.

Anda mungkin sudah tahu tentang kelas Enum . Ia mempunyai ciri khas yang perlu anda ketahui. Khususnya, Enum melaksanakan corak reka bentuk tunggal. Pilihan ini hampir sama dengan pendekatan tunggal yang melibatkan medan awam .

Singleton sebagai enum:


public enum Device {   
    PRINTER	
} 
    

Singleton sebagai pembolehubah awam:


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

Pendekatan enum lebih padat daripada pendekatan medan awam, kerana kita tidak perlu menulis pelaksanaan kita sendiri. Paling penting, enum tidak mempunyai masalah dengan bersiri.

Pensirian enum berfungsi secara berbeza daripada yang dilakukan untuk objek biasa: hanya nilai nama enum yang disiri. Semasa penyahserikatan, kaedah digunakan dengan nama penyahseririan untuk mendapatkan contoh. Selain itu, enum boleh melindungi anda daripada serangan pantulan .

Anda akan mengetahui lebih lanjut tentang refleksi dalam pelajaran dalam modul kedua, di mana kami akan meneroka API Refleksi .

Java melarang instantiating enums — had yang dimasukkan ke dalam pelaksanaan kaedah newInstance kelas Pembina , yang sering dipanggil apabila mencipta objek melalui refleksi.

Petikan kod daripada Constructor.newInstance . Digunakan untuk membuat enum :


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

Kelemahan menggunakan enum untuk mencipta singleton termasuk:

  • Kekurangan pengamulaan malas, kerana objek dibuat serta-merta dan pengamulaan tidak boleh ditangguhkan.

  • Kelas lain tidak boleh dilanjutkan. Iaitu, dalam kes di mana anda perlu mewarisi kelas lain, ia tidak akan berfungsi untuk menggunakan enum sebagai singleton. Dalam kes sedemikian, kita perlu beralih kepada pilihan pelaksanaan lain yang sudah biasa kepada kita: kaedah statik atau pembolehubah awam.

  • Apabila menggunakan enum sebagai singleton, anda hanya boleh menggunakan satu medan enum .


public enum Device extends Electricity { 
    PRINTER 
}
    

Kod ini akan memberi kami ralat penyusunan:

Tiada klausa lanjutan dibenarkan untuk enum

Tetapi jika kita perlu melaksanakan antara muka, tidak ada masalah, kerana enum boleh melaksanakan antara muka:


public enum Device implements Electricity { 
    PRINTER 
}
    

Jika anda tidak perlu menggunakan warisan, sebaiknya laksanakan corak tunggal melalui enum . Kami tidak bersendirian dalam mengesyorkan ini — Joshua Bloch sendiri juga melakukannya .

Pendekatan pelaksanaan ini memberi anda kemudahan, kekompakan, pensirilan di luar kotak, perlindungan daripada serangan pantulan dan keunikan — segala-galanya yang diperlukan oleh singleton yang baik!