[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item3. private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν†€μž„μ„ λ³΄μ¦ν•˜λΌ. ( private μƒμ„±μž + 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ )

2023. 1. 9. 14:51ㆍJAVA/Effective JAVA

728x90

 

μ•„μ΄ν…œ3. private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν†€μž„μ„ λ³΄μ¦ν•˜λΌ. 

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item3. private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν†€μž„μ„ λ³΄μ¦ν•˜λΌ. (private μƒμ„±μž + public static final ν•„λ“œ ) (tistory.com)

 

[μ΄νŽ™ν‹°λΈŒ μžλ°”] Item3. private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν†€μž„μ„ λ³΄μ¦ν•˜λΌ. (private μƒμ„±μž + public

μ•„μ΄ν…œ3. private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν†€μž„μ„ λ³΄μ¦ν•˜λΌ. 싱글톀 singleton μ΄λž€? : μΈμŠ€ν„΄μŠ€λ₯Ό 였직 ν•˜λ‚˜λ§Œ 생성할 수 μžˆλŠ” 클래슀λ₯Ό μ˜λ―Έν•œλ‹€. μ‹±κΈ€ν†€μ˜ μ˜ˆλ‘œλŠ” 섀계상 μœ μΌν•΄μ•Ό ν•˜λŠ” μ‹œμŠ€ν…œ

hyejin.tistory.com

μ—¬κΈ°μ„œ private μƒμ„±μž + public static final ν•„λ“œλ₯Ό μ‚¬μš©ν•œ 첫번째 방법에 λŒ€ν•΄μ„œ μ„€λͺ…ν–ˆλ‹€. 

 

 

싱글톀 singleton λ§Œλ“œλŠ” 방법 2

: private μƒμ„±μž + 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ 

λ‘λ²ˆμ§Έ 싱글톀을 λ§Œλ“œλŠ” λ°©λ²•μœΌλ‘œλŠ” 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό public staic λ©€λ²„λ‘œ μ œκ³΅ν•˜λŠ” 것이닀.

 

public class Elvis 
{
   private static final Elvis INSTANCE = new Elvis();
   
   private Elvis()
   {
   
   }
   
   public static Elvis getInstance()
   {
      return INSTANCE; // return new Elvis();λ₯Ό ν•˜λŠ” μˆœκ°„ 싱글톀 μ•„λ‹ˆκ²Œλ„ λ³€κ²½ κ°€λŠ₯
   }
   
   public void leaveTheBuilding()
   {
      System.out.println("Whoa baby, I'm outta here!");
   }
   

}

Elvis.getInstanceλŠ” 항상 같은 객체의 μ°Έμ‘°λ₯Ό λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— 제2의 Elvis μΈμŠ€ν„΄μŠ€κ°€ λ§Œλ“€μ–΄μ§€μ§€ μ•ŠλŠ”λ‹€!

(ν•˜μ§€λ§Œ μ•žμ—μ„œμ˜ 문제인 λ¦¬ν”Œλ ‰μ…˜μ΄λ‚˜ 역직렬화에 λŒ€ν•œ λ¬Έμ œλŠ” λ™μΌν•˜κ²Œ μΌμ–΄λ‚œλ‹€.) 

 

public static void main(String[] args)
{
   Elvis elvis = Elvis.getInstance();
   elvis.leaveTheBuilding();
   
   System.out.println("Elvis.getInstance() = " + Elvis.getInstance());
   System.out.println("Elvis.getInstance() = " + Elvis.getInstance());
 }

->  같은 μΈμŠ€ν„΄μŠ€κ°€ 좜λ ₯λœλ‹€. 

 

πŸ“’ private μƒμ„±μž + public static final ν•„λ“œ 방법 μž₯단점 

μž₯점 

- APIλ₯Ό 바꾸지 μ•Šκ³ λ„ 싱글톀이 μ•„λ‹ˆκ²Œ λ³€κ²½ν•  수 μžˆλ‹€. 

-> return INSTACNE λΆ€λΆ„λ§Œ new Elvis()둜 μƒˆλ‘œμš΄ 객체 μƒμ„±μœΌλ‘œ λ³€κ²½ν•΄μ£Όλ©΄ λœλ‹€. 

 

 

 

- 정적 νŒ©ν„°λ¦¬λ₯Ό μ œλ„€λ¦­ 싱글톀 νŒ©ν„°λ¦¬λ‘œ λ§Œλ“€ 수 μžˆλ‹€. 

public class MetaElvis<T>
{
   private static final MetaElvis<Object> INSTANCE = new MetaElvis();
   
   private MetaElvis()
   {
   
   }
   
   @SuppressWarnings("unchecked")
   public static <T> MetaElvis<T> getInstance()
   {
      return (MetaElvis<T>) INSTANCE; // μ›ν•˜λŠ” νƒ€μž…μœΌλ‘œ ν˜•λ³€ν™˜ ν•  수 μžˆλ‹€.
   }
   
   public void say(T t)
   {
      System.out.println("t = " + t);
   }
   
   public void leaveTheBuilding()
   {
      System.out.println("Whoa baby, I'm outta here!");
   }
}
MetaElvis<String> metaElvis1 = MetaElvis.getInstance();
MetaElvis<Integer> metaElvis2 = MetaElvis.getInstance();

// == λΉ„κ΅λŠ” μ œλ‹ˆλ¦­ νƒ€μž…μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— == λŠ” μ•ˆλœλ‹€.
System.out.println(
      "(Objects.equals(metaElvis1, metaElvis2)) = " + (Objects.equals(metaElvis1, metaElvis2))); // ν•΄μ‹œμ½”λ“œκ°€ κ°™κ³  같은 μΈμŠ€ν„΄μŠ€

-> ν…ŒμŠ€νŠΈ 해보면 metaElvis1κ³Ό metaElvis2λŠ” ν•΄μ‹œμ½”λ“œλ„ 같은 μΈμŠ€ν„΄μŠ€μ΄μ§€λ§Œ μ œλ„€λ¦­ νƒ€μž…μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— == λΉ„κ΅λŠ” μ•ˆλ˜μ§€λ§Œ Objects.equals()λ₯Ό 톡해 비ꡐ해보면 λ™μΌν•œ 것을 확인할 수 μžˆλ‹€. 

 

- 정적 νŒ©ν„°λ¦¬μ˜ λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό κ³΅κΈ‰μž Supplier둜 μ‚¬μš©ν•  수 μžˆλ‹€. 

public interface Singer
{
   void sing();
}
public class Concert
{
   public void start(Supplier<Singer> singerSupplier)
   {
      Singer singer = singerSupplier.get();
      singer.sing();
   }
}
// private μƒμ„±μž + 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ
// μž₯점: 정적 νŒ©ν„°λ¦¬μ˜ λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό supplier의 κ³΅κΈ‰μžλ‘œ μ‚¬μš©ν• μˆ˜ μžˆλ‹€λŠ” 점
Concert concert = new Concert();
concert.start(Elvis::getInstance);

 

단점 

- 싱글톀을 μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλ₯Ό ν…ŒμŠ€νŠΈν•˜κΈ° μ–΄λ €μ›Œμ§„λ‹€. 

- λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ private μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€. 

- 역직렬화λ₯Ό ν•  λ•Œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€κ°€ 생길 수 μžˆλ‹€. 

 

 

 

 

싱글톀 singleton λ§Œλ“œλŠ” 방법 3

: μ—΄κ±° νƒ€μž…  

public enum Elvis
{
   INSTANCE;
   
   public void leaveTheBuilding()
   {
      System.out.println("Elvis.leaveTheBuilding");
   }
   
   
}

μ„Έλ²ˆμ§Έ λ°©λ²•μœΌλ‘œλŠ” μ›μ†Œκ°€ ν•˜λ‚˜μΈ μ—΄κ±° νƒ€μž…μ„ μ„ μ–Έν•˜λŠ” 것이닀. 

이 방법을 μ‚¬μš©ν•˜λ©΄ public ν•„λ“œμ™€ λΉ„μŠ·ν•˜μ§€λ§Œ 더 κ°„κ²°ν•˜κ³  μΆ”κ°€ λ…Έλ ₯ 없이 직렬화 ν•  수 있으며,  λ¦¬ν”Œλ ‰μ…˜ μƒν™©μ—μ„œλ„ μΈμŠ€ν„΄μŠ€ 생성을 μ™„λ²½νžˆ 막아쀀닀. 

 

public static void main(String[] args)
{
   Elvis elvis = Elvis.INSTANCE;
   elvis.leaveTheBuilding();
}

λŒ€λΆ€λΆ„μ˜ μƒν™©μ—μ„œλŠ” μ›μ†Œκ°€ ν•˜λ‚˜λΏμΈ μ—΄κ±° νƒ€μž…μ΄ 싱글톀을 λ§Œλ“œλŠ”λ° κ°€μž₯ 쒋은 방법이닀~_~ 

 

단, λ§Œλ“€λ €λŠ” 싱글턴이 Enum μ™Έμ˜ 클래슀λ₯Ό 상속해야 ν•œλ‹€λ©΄ 이 방법은 μ‚¬μš©ν•  수 μ—†λ‹€. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90