λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Backend/Java

[Java]싱글톀 클래슀(Singleton Class)

by sukii 2024. 1. 25.
λ°˜μ‘ν˜•

πŸ€”μ‹±κΈ€ν†€ 클래슀(Singleton Class) : 싱글톀 λ””μžμΈ νŒ¨ν„΄μ„ μ μš©ν•˜μ—¬ μž‘μ„±λœ 클래슀
=> ν”„λ‘œκ·Έλž¨μ— 객체λ₯Ό ν•˜λ‚˜λ§Œ μ œκ³΅ν•˜κΈ° μœ„ν•œ λͺ©μ μ˜ 클래슀λ₯Ό μž‘μ„±ν•˜κΈ° μœ„ν•΄ μ‚¬μš©
=> ν”„λ‘œκ·Έλž¨μ— λΆˆν•„μš”ν•œ 객체가 μ—¬λŸ¬κ°œ μƒμ„±λ˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•œ λ””μžμΈ νŒ¨ν„΄
=> 일반적으둜 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” κΈ°λŠ₯의 λ©”μ†Œλ“œλ§Œ μž‘μ„±λœ 클래슀λ₯Ό μ„ μ–Έν•  경우 싱글톀 λ””μžμΈ νŒ¨ν„΄μ„ μ μš©ν•˜μ—¬ 클래슀 μ„ μ–Έν•˜λŠ” 것을 ꢌμž₯

 

 

βš«μ‹±κΈ€ν†€ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λŠ” 이유

 GPTμ—κ²Œ λ¬Όμ–΄λ³΄λ‹ˆ 싱글톀 νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λŠ” μ΄μœ λŠ” μ•„λž˜μ™€ κ°™μŒ.

  1. μžμ› 곡유: μ—¬λŸ¬ κ³³μ—μ„œ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό κ³΅μœ ν•˜κ³ μž ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²°, λ‘œκΉ…, μ„€μ • 관리 λ“±μ˜ κ³΅ν†΅λœ μžμ›μ— λŒ€ν•œ 접근을 ν†΅μΌμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
  2. μ „μ—­ μƒνƒœ μœ μ§€: μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄μ—μ„œ κ³΅μœ ν•΄μ•Ό ν•˜λŠ” μ „μ—­ μƒνƒœλ₯Ό μœ μ§€ν•˜κ³  관리할 λ•Œ μœ μš©ν•©λ‹ˆλ‹€.
  3. μžμ› μ ˆμ•½: μ—¬λŸ¬ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ” 것이 λΉ„νš¨μœ¨μ μ΄κ±°λ‚˜ λΆ€μ μ ˆν•œ 경우, λ©”λͺ¨λ¦¬λ₯Ό μ ˆμ•½ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

βš«μ‹±κΈ€ν†€ 클래슀 μž‘μ„±λ²•

1) 클래슀둜 μƒμ„±λœ 객체λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ ν•„λ“œ μž‘μ„±
=> static μ œν•œμžλ₯Ό μ‚¬μš©ν•˜μ—¬ 정적 ν•„λ“œλ‘œ μž‘μ„±

*μ‹œμŠ€ν…œ ν•„λ“œ : 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš©ν•  λͺ©μ μ˜ ν•„λ“œ
=> Getter λ©”μ†Œλ“œ 및 Setter λ©”μ†Œλ“œλ₯Ό μž‘μ„±ν•˜μ§€ μ•ŠλŠ” ν•„λ“œ

// => μΌλ°˜μ μΈ ν•„λ“œμ™€ κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ ν•„λ“œλͺ…을 [_]둜 μ‹œμž‘λ˜λ„λ‘ μž‘μ„±ν•˜λŠ” κ²ƒμ„ κΆŒμž₯

private static Singleton _instance;

 

 

2) μƒμ„±μžλŠ” private μ ‘κ·Ό μ œν•œμžλ₯Ό μ‚¬μš©ν•˜μ—¬ μ€λ‹‰ν™”λ˜λ„λ‘ μž‘μ„±
=> 클래슀 μ™ΈλΆ€μ—μ„œ new μ—°μ‚°μžλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄ 객체λ₯Ό μƒμ„±ν•˜μ§€ λͺ»ν•˜λ„둝 은닉화 처리

private Singleton() {
}

 

 

3) μ•„λž˜μ™€ 같이 정적 μ˜μ—­ μ•ˆμ— new μ—°μ‚°μžλ‘œ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό μƒμ„±ν•˜μ—¬ ν•„λ“œμ— μ €μž₯

정적 μ˜μ—­(Static Block) : 클래슀λ₯Ό 읽어 λ©”λͺ¨λ¦¬(MethodArea)에 μ €μž₯된 ν›„ μžλ™μœΌλ‘œ 싀행될 λͺ…령을 μž‘μ„±ν•˜κΈ° μœ„ν•œ μ˜μ—­
=> ν”„λ‘œκ·Έλž¨μ—μ„œ λ©”λͺ¨λ¦¬(MethodArea)에 클래슀λ₯Ό μ €μž₯ν•œ ν›„ ν•œλ²ˆλ§Œ μ‹€ν–‰λ˜λŠ” λͺ…λ Ή
=> 정적 ν•„λ“œ 및 정적 λ©”μ†Œλ“œλ§Œ μ‚¬μš© κ°€λŠ₯

static {
	_instance=new Singleton();
}

 

4) ν•„λ“œμ— μ €μž₯된 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œ μž‘μ„±
=> 클래슀둜 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ„λ‘ 정적 λ©”μ†Œλ“œλ‘œ μž‘μ„±

public static Singleton getInstance() {
	return _instance;
}

 

5) μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œ μž‘μ„±

=> 기타 ν•„μš”ν•œ λ©”μ†Œλ“œλ“€ μž‘μ„±ν•˜λ©΄ 됨. display()λΌλŠ” λ©”μ†Œλ“œλŠ” 싱글톀 ν΄λž˜μŠ€κ°€ μ–΄λ–»κ²Œ μž‘λ™ν•˜λŠ”μ§€ 보기 μœ„ν•œ λ©”μ†Œλ“œ

public void display() {
	System.out.println("Singleton 클래슀의 display() λ©”μ†Œλ“œ 호좜");
}

 

 

 

 

βš«μ‹±κΈ€ν†€ 클래슀λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•œ Singleton App Class μ‚΄νŽ΄λ³΄κΈ°

1) λ¨Όμ € new μ—°μ‚°μžλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ 객체 생성해봄

=> λ‹Ήμ—°νžˆ μ—λŸ¬ 떨어짐. μƒμ„±μžκ°€ private μ œν•œμžλ₯Ό μ‚¬μš©ν•˜μ—¬ 은닉화 μ²˜λ¦¬λ˜μ–΄ μžˆμœΌλ‹ˆκΉŒ

 

 

 

2) 싱글톀 ν΄λž˜μŠ€λŠ” 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ†Œλ“œλ₯Ό 클래슀둜 ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό λ°˜ν™˜λ°›μ•„ μ°Έμ‘°λ³€μˆ˜μ— μ €μž₯ν•  수 있음

=> 정적 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 클래슀 내뢀에 미리 μƒμ„±λœ ν•˜λ‚˜μ˜ κ°μ²΄λ§Œμ„ μ œκ³΅λ°›μ•„ λ°˜ν™˜

=> κ·ΈλŸ¬λ―€λ‘œ μœ„ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ•„λž˜μ™€ 같이 singleton 1이든 singleton2λ“  같은 μ£Όμ†Œλ₯Ό μ°Έμ‘°ν•˜λŠ” 것을 μ•Œ 수 있음

singleton1 = oop.Singleton@6f2b958e

singleton2 = oop.Singleton@6f2b958e

Singleton 클래슀의 display() λ©”μ†Œλ“œ 호좜

Singleton 클래슀의 display() λ©”μ†Œλ“œ 호좜

 

 

 

3)싱글톀 ν΄λž˜μŠ€λŠ” μ°Έμ‘°λ³€μˆ˜μ— 객체λ₯Ό μ €μž₯ν•˜μ—¬ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³  객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•΄ 객체λ₯Ό λ°˜ν™˜ 받은 ν›„ 직접 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ‚¬μš©

=> 2번 방법보닀 이게 μ½”λ“œκ°€ κ°„κ²°ν•΄μ§€λ‹ˆκΉŒ μ’‹μŒ

Singleton.getInstance().display();

 

=>μœ„ μ½”λ“œ μ‹€ν–‰ν•˜λ©΄ μ•„λž˜μ™€ 같이 2λ²ˆμ—μ„œ ν˜ΈμΆœν•œ 것과 λ˜‘κ°™μ€ κ²°κ³Όκ°€ 좜λ ₯λ˜λŠ” 것을 λ³Ό 수 있음

Singleton 클래슀의 display() λ©”μ†Œλ“œ 호좜

 

 

 

 


μœ„ μ‹€μŠ΅ μ½”λ“œ μ „μ²΄πŸ‘©‍πŸ’»

package oop;

public class Singleton {
	//클래슀둜 μƒμ„±λœ 객체λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ ν•„λ“œ μž‘μ„±
	// => static μ œν•œμžλ₯Ό μ‚¬μš©ν•˜μ—¬ 정적 ν•„λ“œλ‘œ μž‘μ„±
	//μ‹œμŠ€ν…œ ν•„λ“œ : 클래슀 λ‚΄λΆ€μ—μ„œλ§Œ μ‚¬μš©ν•  λͺ©μ μ˜ ν•„λ“œ
	// => Getter λ©”μ†Œλ“œ 및 Setter λ©”μ†Œλ“œλ₯Ό μž‘μ„±ν•˜μ§€ μ•ŠλŠ” ν•„λ“œ
	// => 일반적인 ν•„λ“œμ™€ κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ ν•„λ“œλͺ…을 [_]둜 μ‹œμž‘λ˜λ„λ‘ μž‘μ„±ν•˜λŠ” 것을 ꢌμž₯
	private static Singleton _instance;

	//μƒμ„±μžλŠ” private μ ‘κ·Ό μ œν•œμžλ₯Ό μ‚¬μš©ν•˜μ—¬ μ€λ‹‰ν™”λ˜λ„λ‘ μž‘μ„±
	// => 클래슀 μ™ΈλΆ€μ—μ„œ new μ—°μ‚°μžλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄ 객체λ₯Ό μƒμ„±ν•˜μ§€ λͺ»ν•˜λ„둝 은닉화 처리
	private Singleton() {
		
	}
	
	//정적 μ˜μ—­(Static Block) : 클래슀λ₯Ό 읽어 λ©”λͺ¨λ¦¬(MethodArea)에 μ €μž₯된 ν›„ μžλ™μœΌλ‘œ 싀행될
	//λͺ…령을 μž‘μ„±ν•˜κΈ° μœ„ν•œ μ˜μ—­
	// => ν”„λ‘œκ·Έλž¨μ—μ„œ λ©”λͺ¨λ¦¬(MethodArea)에 클래슀λ₯Ό μ €μž₯ν•œ ν›„ ν•œλ²ˆλ§Œ μ‹€ν–‰λ˜λŠ” λͺ…λ Ή
	// => 정적 ν•„λ“œ 및 정적 λ©”μ†Œλ“œλ§Œ μ‚¬μš© κ°€λŠ₯
	static {
		//new μ—°μ‚°μžλ‘œ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό μƒμ„±ν•˜μ—¬ ν•„λ“œμ— μ €μž₯
		// => ν”„λ‘œκ·Έλž¨ μ‹€ν–‰
		_instance=new Singleton();
	}

	//ν•„λ“œμ— μ €μž₯된 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œ
	// =>클래슀둜 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ„λ‘ 정적 λ©”μ†Œλ“œλ‘œ μž‘μ„±
	public static Singleton getInstance() {
		return _instance;
	}
	
	//μΈμŠ€ν„΄μŠ€ λ©”μ†Œλ“œ μž‘μ„±
	public void display() {
		System.out.println("Singleton 클래슀의 display() λ©”μ†Œλ“œ 호좜");
	}
}

 

package oop;

public class SingletonApp {
	public static void main(String[] args) {
		/*
		//new μ—°μ‚°μžλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό 생성해 μ°Έμ‘°λ³€μˆ˜μ— μ €μž₯
		// => 객체λ₯Ό μ—¬λŸ¬ 개 μƒμ„±ν•˜μ—¬ μ°Έμ‘°λ³€μˆ˜μ— λ”°λ‘œ μ €μž₯ν•˜μ—¬ μ°Έμ‘°λ³€μˆ˜λ‘œ 객체λ₯Ό μ°Έμ‘°ν•΄ λ©”μ†Œλ“œ 호좜
		Singleton singleton1=new Singleton();
		Singleton singleton2=new Singleton();
		
		System.out.println("singleton1 = "+singleton1);
		System.out.println("singleton2 = "+singleton2);
		singleton1.display();
		singleton2.display();
		 */
		
		
		//싱글톀 ν΄λž˜μŠ€λŠ” μƒμ„±μžκ°€ 은닉화 μ²˜λ¦¬λ˜μ–΄ new μ—°μ‚°μžλ‘œ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄ 객체 생성 λΆˆκ°€
		//Singleton singleton1=new Singleton();
		
		//싱글톀 ν΄λž˜μŠ€λŠ” 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” 정적 λ©”μ†Œλ“œλ₯Ό 클래슀둜 ν˜ΈμΆœν•˜μ—¬ 객체λ₯Ό λ°˜ν™˜λ°›μ•„
		//μ°Έμ‘°λ³€μˆ˜μ— μ €μž₯
		// => 정적 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ 클래슀 내뢀에 미리 생성 ν•˜λ‚˜μ˜ κ°μ²΄λ§Œμ„ μ œκ³΅λ°›μ•„ λ°˜ν™˜
		Singleton singleton1=Singleton.getInstance();
		Singleton singleton2=Singleton.getInstance();
		
		System.out.println("singleton1 = "+singleton1);
		System.out.println("singleton2 = "+singleton2);
		
		singleton1.display();
		singleton2.display();
		System.out.println("==============================================================");
		
		//싱글톀 ν΄λž˜μŠ€λŠ” μ°Έμ‘°λ³€μˆ˜μ— 객체λ₯Ό μ €μž₯ν•˜μ—¬ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³ 
		//객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•΄ 객체λ₯Ό λ°˜ν™˜ 받은 ν›„ 직접 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ‚¬μš©
		Singleton.getInstance().display();
		//Singleton.getInstance().display();
		System.out.println("==============================================================");
	}
}
λ°˜μ‘ν˜•