์‹ฑ๊ธ€ํ†ค ์‹ฑ๊ธ€๋ชฐํŠธ ์Šค์นด์น˜ ์œ„์Šคํ‚ค๊ฐ€ ์ข‹๋‹ค๋Š” ๋ง์„ ๋“ค์–ด๋ณด์…จ๋‚˜์š”? ์Œ, ์ˆ ์€ ๊ฑด๊ฐ•์— ์ข‹์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์˜ค๋Š˜์€ ๋Œ€์‹  Java์˜ ์‹ฑ๊ธ€ํ†ค ๋””์ž์ธ ํŒจํ„ด์— ๋Œ€ํ•ด ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด์ „์— ๊ฐ์ฒด ์ƒ์„ฑ์„ ๊ฒ€ํ† ํ–ˆ์œผ๋ฏ€๋กœ Java์—์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


Robot robot = new Robot(); 
    

ํ•˜์ง€๋งŒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜๋งŒ ์ƒ์„ฑ๋˜๋„๋ก ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”?

new Robot() ๋ฌธ์€ ๋งŽ์€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ทธ๋ ‡๊ฒŒ ํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ์—†์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์‹ฑ๊ธ€ํ†ค ํŒจํ„ด์ด ๊ตฌ์ถœ๋˜๋Š” ๊ณณ์ž…๋‹ˆ๋‹ค.

ํ”„๋ฆฐํ„ฐ์— ์—ฐ๊ฒฐํ•  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(๋‹จ์ง€ ํ”„๋ฆฐํ„ฐ ํ•˜๋‚˜๋งŒ)์„ ์ž‘์„ฑํ•˜๊ณ  ์ธ์‡„ํ•˜๋ผ๊ณ  ์ง€์‹œํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


public class Printer { 
 
	public Printer() { 
	} 
     
	public void print() { 
    	โ€ฆ 
	} 
}
    

์ด๊ฒƒ์€ ํ‰๋ฒ”ํ•œ ์ˆ˜์—…์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ... ํ•˜์ง€๋งŒ! ํ•˜๋‚˜์˜ "ํ•˜์ง€๋งŒ"์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋ฆฐํ„ฐ ๊ฐœ์ฒด์˜ ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค๋ฅธ ์œ„์น˜์—์„œ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ํ”„๋ฆฐํ„ฐ๊ฐ€ ์†์ƒ๋˜๊ฑฐ๋‚˜ ํŒŒ์†๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” ํ”„๋ฆฐํ„ฐ์˜ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•˜๋ฉฐ ์ด๊ฒƒ์ด ์‹ฑ๊ธ€ํ†ค์ด ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•  ์ผ์ž…๋‹ˆ๋‹ค!

์‹ฑ๊ธ€ํ†ค์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•

์‹ฑ๊ธ€ํ†ค์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์—๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ฐœ์ธ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
  • ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๊ณต์šฉ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.

๋จผ์ € ๊ฐœ์ธ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๋ฉด ํด๋ž˜์Šค์—์„œ ํ•„๋“œ๋ฅผ final ๋กœ ์„ ์–ธํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์„ final ๋กœ ํ‘œ์‹œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๊ฒƒ์ด ๋ถˆ๋ณ€ ์ด๋ผ๋Š” ๊ฒƒ์„ ์••๋‹ˆ๋‹ค . ์ฆ‰, ๋” ์ด์ƒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ƒ์„ฑ์ž๋ฅผ ์ „์šฉ ์œผ๋กœ ์„ ์–ธํ•˜์—ฌ ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ ๊ฐœ์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋„๋ก ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค . ์ด๋Š” ํ”„๋กœ๊ทธ๋žจ์— ํ”„๋ฆฐํ„ฐ์˜ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๊ฐ€ ์—†์Œ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ์ž๋Š” ์ดˆ๊ธฐํ™” ์ค‘์— ํ•œ ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋˜๋ฉฐ Printer ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค .


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

์šฐ๋ฆฌ๋Š” ๊ฐœ์ธ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ PRINTER ์‹ฑ๊ธ€ํ†ค์„ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋งŒํผ์ธ์‡„๊ธฐ๋ณ€์ˆ˜๋Š” ์–ด๋–ค ๊ฐ์ฒด์—๋„ ์†ํ•˜์ง€ ์•Š๊ณ  Printer ํด๋ž˜์Šค ์ž์ฒด์— ์†ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ •์  ์ˆ˜์ •์ž๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค .

์ด์ œ ํด๋ž˜์Šค์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค(๊ทธ๋ฆฌ๊ณ  ์ด์ œ ํ•„๋“œ๋Š” private ์ž…๋‹ˆ๋‹ค ).


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

์—ฌ๊ธฐ์—์„œ getInstance() ๋ฉ”์„œ๋“œ๋ฅผ ๋ช‡ ๋ฒˆ ํ˜ธ์ถœํ•˜๋”๋ผ๋„ ํ•ญ์ƒ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.์ธ์‡„๊ธฐ๋ฌผ์ฒด.

๊ฐœ์ธ ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ฑ๊ธ€ํ†ค์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋” ๊ฐ„๋‹จํ•˜๊ณ  ๊ฐ„๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ public ํ•„๋“œ๊ฐ€ final ๋กœ ์„ ์–ธ๋˜์–ด ํ•ญ์ƒ ๋™์ผํ•œ ๊ฐœ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋ฅผ ํฌํ•จํ•˜๋„๋ก ๋ณด์žฅํ•˜๋ฏ€๋กœ API๊ฐ€ ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ •์  ๋ฉ”์„œ๋“œ ์˜ต์…˜์€ API๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ์‹ฑ๊ธ€ํ†ค์„ ๋น„์‹ฑ๊ธ€ํ†ค ํด๋ž˜์Šค๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. getInstance () ๋ฉ”์„œ๋“œ๋Š” ๊ฐœ์ฒด์˜ ๋‹จ์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•˜์ง€๋งŒ ์ด๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฐ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

static ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ์ผ๋ฐ˜์ ์ธ ์‹ฑ๊ธ€ํ†ค ํŒฉํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ •์  ์˜ต์…˜์˜ ๋งˆ์ง€๋ง‰ ์ด์ ์€ ๋ฉ”์„œ๋“œ ์ฐธ์กฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์žฅ์ ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๊ณต๊ฐœ ํ•„๋“œ์™€ ๊ด€๋ จ๋œ ์˜ต์…˜์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ Serializable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ readResolve ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค . ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์—ญ์ง๋ ฌํ™” ์ค‘์— ์ƒˆ ์‹ฑ๊ธ€ํ†ค ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๊ฐœ์ฒด์˜ ์ƒํƒœ๋ฅผ ์ผ๋ จ์˜ ๋ฐ”์ดํŠธ๋กœ ์ €์žฅํ•˜๋ ค๋ฉด ์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•˜๊ณ  ํ•ด๋‹น ๋ฐ”์ดํŠธ์—์„œ ๊ฐœ์ฒด๋ฅผ ๋ณต์›ํ•˜๋ ค๋ฉด ์—ญ์ง๋ ฌํ™”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™”์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ด ๊ธฐ์‚ฌ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค .

์ด์ œ ์‹ฑ๊ธ€ํ†ค์„ ๋‹ค์‹œ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.


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

์ด์ œ ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™”ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜ ์˜ˆ์ œ๋Š” Java์˜ ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™”๋ฅผ ์œ„ํ•œ ํ‘œ์ค€ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. "I/O ์ŠคํŠธ๋ฆผ"(Java Syntax ๋ชจ๋“ˆ์—์„œ) ๋ฐ "Serialization"(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);
    

๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์‹ฑ๊ธ€ํ†ค 1: Printer@6be46e8f
์‹ฑ๊ธ€ํ†ค 2: Printer@3c756e4d

์—ฌ๊ธฐ์—์„œ ์—ญ์ง๋ ฌํ™”๊ฐ€ ์šฐ๋ฆฌ์—๊ฒŒ ์‹ฑ๊ธ€ํ†ค์˜ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ–ˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํด๋ž˜์Šค์— readResolve ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค .


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; 
	} 
}
    

์ด์ œ ์‹ฑ๊ธ€ํ†ค์„ ๋‹ค์‹œ ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.


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); 
    

๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ๋Š” ๋‹ค์Œ์„ ์–ป์Šต๋‹ˆ๋‹ค.

์‹ฑ๊ธ€ํ†ค 1: com.company.Printer@6be46e8f
์‹ฑ๊ธ€ํ†ค 2: com.company.Printer@6be46e8f

readResolve () ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ญ์ง๋ ฌํ™”ํ•œ ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ถˆ๋Ÿ‰ ์‹ฑ๊ธ€ํ†ค ์ƒ์„ฑ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์•ฝ

์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” ์‹ฑ๊ธ€ํ†ค์— ๋Œ€ํ•ด ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. ์‹ฑ๊ธ€ํ†ค์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ์‚ฌ์šฉ ์‹œ๊ธฐ, ์šฉ๋„, ์ƒ์„ฑ์„ ์œ„ํ•ด Java์—์„œ ์ œ๊ณตํ•˜๋Š” ์˜ต์…˜. ๋‘ ์˜ต์…˜์˜ ํŠน์ • ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ฐœ์ธ ์ƒ์„ฑ์ž ์ •์  ๋ฐฉ๋ฒ•
  • ๋” ์‰ฝ๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ
  • ์‹ฑ๊ธ€ํ†ค ํ•„๋“œ๊ฐ€ ๊ณต๊ฐœ ์ตœ์ข… ์ด๋ฏ€๋กœ ๋ช…๋ฐฑํ•œ API
  • ๋ฉ”์„œ๋“œ ์ฐธ์กฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ผ๋ฐ˜ ์‹ฑ๊ธ€ํ†ค ํŒฉํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ฐ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ๋ณ„๋„์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.