Mbok sampeyan wis krungu sing Singleton single malt Scotch wiski apik? Nah, alkohol iku ora becik kanggo kesehatan, mula dina iki kita bakal ngandhani babagan pola desain singleton ing Jawa.

Kita sadurunge nyemak nggawe obyek, supaya kita ngerti manawa kanggo nggawe obyek ing Jawa, sampeyan kudu nulis kaya:


Robot robot = new Robot(); 
    

Nanging apa yen kita pengin mesthekake yen mung siji conto saka kelas digawe?

Pernyataan Robot anyar () bisa nggawe akeh obyek, lan ora ana sing ngalangi. Iki ngendi pola singleton teka kanggo ngluwari.

Upamane sampeyan kudu nulis aplikasi sing bakal nyambung menyang printer - mung siji printer - lan menehi printah:


public class Printer { 
 
	public Printer() { 
	} 
     
	public void print() { 
    	… 
	} 
}
    

Iki katon kaya kelas biasa ... TAPI! Ana siji "nanging": Aku bisa nggawe sawetara kedadean saka obyek printer lan nelpon cara ing panggonan sing beda-beda. Iki bisa ngrusak utawa malah ngrusak printerku. Dadi, kita kudu mesthekake yen mung ana siji conto printer kita, lan iku sing bakal ditindakake dening singleton kanggo kita!

Cara nggawe singleton

Ana rong cara kanggo nggawe singleton:

  • nggunakake konstruktor pribadi;
  • ngekspor cara statis umum kanggo nyedhiyakake akses menyang siji conto.

Ayo dadi nimbang nggunakake konstruktor pribadi. Kanggo nindakake iki, kita kudu ngumumake lapangan minangka final ing kelas kita lan miwiti. Amarga kita wis menehi tandha minangka final , kita ngerti manawa ora bisa diganti , yaiku kita ora bisa ngganti maneh.

Sampeyan uga kudu ngumumake konstruktor minangka pribadi kanggo nyegah nggawe obyek ing njaba kelas . Iki njamin kanggo kita yen ora bakal ana conto printer liyane ing program kasebut. Konstruktor bakal diarani mung sapisan sajrone initialization lan bakal nggawe Printer kita :


public class Printer { 
     
	public static final Printer PRINTER = new Printer(); 
     
	private Printer() { 
	} 
 
	public void print() { 
        // Printing... 
 
	} 
}
    

Kita nggunakake konstruktor pribadi kanggo nggawe PRINTER singleton - mung bakal ana siji conto. IngPRINTERvariabel nduweni modifier statis , amarga ora kalebu obyek, nanging kelas Printer dhewe.

Saiki ayo nimbang nggawe singleton nggunakake metode statis kanggo nyedhiyakake akses menyang conto siji saka kelas kita (lan cathet yen lapangan saiki pribadi ):


public class Printer { 
 
	private static final Printer PRINTER = new Printer(); 
 
	private Printer() { 
	} 
 
	public static Printer getInstance() { 
    	return PRINTER; 
	} 
     
	public void print() { 
        // Printing... 
	} 
} 
    

Ora ketompo carane kakehan kita nelpon getInstance () cara kene, kita bakal tansah njaluk padhaPRINTERobyek.

Nggawe singleton nggunakake konstruktor pribadi luwih prasaja lan luwih ringkes. Apa maneh, API kasebut jelas, amarga lapangan umum diumumake minangka final , sing njamin bakal ngemot referensi kanggo obyek sing padha.

Pilihan cara statis menehi kita keluwesan kanggo ngganti singleton menyang kelas non-singleton tanpa ngganti API sawijining. Metode getInstance () menehi conto siji obyek, nanging kita bisa ngganti supaya bisa ngasilake conto sing kapisah kanggo saben pangguna sing nelpon.

Opsi statis uga ngidini kita nulis pabrik singleton umum.

Keuntungan pungkasan saka opsi statis yaiku sampeyan bisa nggunakake kanthi referensi metode.

Yen sampeyan ora mbutuhake kaluwihan ing ndhuwur, mula disaranake nggunakake pilihan sing kalebu lapangan umum .

Yen kita butuh serialisasi, mula ora cukup mung ngleksanakake antarmuka Serializable . Kita uga kudu nambah metode readResolve , yen ora, kita bakal entuk conto singleton anyar sajrone deserialization.

Serialisasi dibutuhake kanggo nyimpen kahanan obyek minangka urutan bita, lan deseralisasi dibutuhake kanggo mulihake obyek kasebut saka bait kasebut. Sampeyan bisa maca liyane babagan serialization lan deserialization ing artikel iki .

Saiki ayo nulis ulang singleton kita:


public class Printer implements Serializable { 
 
	private static final Printer PRINTER = new Printer(); 
 
	private Printer() { 
	} 
 
	public static Printer getInstance() { 
    	return PRINTER; 
	} 
} 
    

Saiki kita bakal nggawe serial lan deserialize.

Elinga yen conto ing ngisor iki minangka mekanisme standar kanggo serialisasi lan deseralisasi ing Jawa. Pangerten lengkap babagan apa sing kedadeyan ing kode bakal teka sawise sampeyan sinau "I / O streams" (ing modul Java Syntax) lan "Serialization" (ing modul Java Core).

var printer = Printer.getInstance(); 
var fileOutputStream = new FileOutputStream("printer.txt"); 
var objectOutputStream = new ObjectOutputStream(fileOutputStream); 
objectOutputStream.writeObject(printer); 
objectOutputStream.close(); 
 
var fileInputStream = new FileInputStream("printer.txt"); 
var objectInputStream = new ObjectInputStream(fileInputStream); 
var deserializedPrinter =(Printer) objectInputStream.readObject(); 
objectInputStream.close(); 
 
System.out.println("Singleton 1 is: " + printer); 
System.out.println("Singleton 2 is: " + deserializedPrinter);
    

Lan kita entuk asil iki:

Singleton 1 yaiku: Printer@6be46e8f
Singleton 2 yaiku: Printer@3c756e4d

Ing kene kita weruh yen deserialization menehi conto sing beda saka singleton kita. Kanggo ndandani iki, ayo nambah metode readResolve menyang kelas kita:


public class Printer implements Serializable { 
 
	private static final Printer PRINTER = new Printer(); 
 
	private Printer() { 
	} 
 
	public static Printer getInstance() { 
    	return PRINTER; 
	} 
 
	public Object readResolve() { 
    	return PRINTER; 
	} 
}
    

Saiki kita bakal nggawe serial lan deserialize singleton maneh:


var printer = Printer.getInstance(); 
var fileOutputStream = new FileOutputStream("printer.txt"); 
var objectOutputStream = new ObjectOutputStream(fileOutputStream); 
objectOutputStream.writeObject(printer); 
objectOutputStream.close(); 
 
var fileInputStream = new FileInputStream("printer.txt"); 
var objectInputStream = new ObjectInputStream(fileInputStream); 
var deserializedPrinter=(Printer) objectInputStream.readObject(); 
objectInputStream.close(); 
 
System.out.println("Singleton 1 is: " + printer); 
System.out.println("Singleton 2 is: " + deserializedPrinter); 
    

Lan kita entuk:

Singleton 1 yaiku: com.company.Printer@6be46e8f
Singleton 2 yaiku: com.company.Printer@6be46e8f

Cara readResolve () ngidini kita entuk obyek sing padha karo deserialized, saéngga nyegah nggawe singleton nakal.

Ringkesan

Dina iki kita sinau babagan singletons: carane nggawe lan kapan digunakake, apa gunane, lan opsi apa sing ditawakake Jawa kanggo nggawe. Fitur khusus saka loro opsi kasebut diwenehi ing ngisor iki:

Konstruktor pribadi Metode statis
  • Luwih gampang lan luwih ringkes
  • API sing jelas amarga lapangan singleton minangka final umum
  • Bisa digunakake kanthi referensi metode
  • Bisa digunakake kanggo nulis pabrik singleton umum
  • Bisa digunakake kanggo ngasilake conto sing kapisah kanggo saben pangguna