Amenable
Amenable's Blog
Amenable
  • λΆ„λ₯˜ 전체보기 (189)
    • πŸ“‚ JAVA (87)
      • μ΄νŽ™ν‹°λΈŒ μžλ°” (65)
      • μ£Όμš” κ°œλ… (22)
    • πŸ“‚ 개발 μ„œμ  (22)
      • μ‹€μš©μ£Όμ˜ ν”„λ‘œκ·Έλž˜λ¨Έ (1)
      • 객체지ν–₯의 사싀과 μ˜€ν•΄ (2)
      • 클린 μ½”λ“œ (8)
      • ν•¨κ»˜ 자라기 (1)
      • 그림으둜 λ°°μš°λŠ” HTTP&Network Basic (10)
    • πŸ“‚ λ°μ΄ν„°λ² μ΄μŠ€ (8)
      • κ°œλ… (8)
      • λ¬Έμ œν’€μ΄ (0)
    • πŸ“‚ λ„€νŠΈμ›Œν¬ (14)
      • κ°œλ… (6)
      • 성곡과 μ‹€νŒ¨λ₯Ό κ²°μ •ν•˜λŠ” 1%의 λ„€νŠΈμ›Œν¬ 원리 (8)
    • πŸ“‚ μŠ€ν”„λ§ (13)
      • κΈ°λ³Έ κ°œλ… (13)
    • πŸ“‚ WEB (5)
    • πŸ“‚ 자료ꡬ쑰 (12)
      • κ°œλ… (2)
      • μ •λ ¬ (8)
      • 트리 (2)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜ (10)
      • μ΅œμ†Œμ‹ μž₯트리 (2)
      • μ΅œλ‹¨ 경둜 (2)
      • λ¬Έμžμ—΄ (2)
      • ETC (4)
    • πŸ“‚ μ•Œκ³ λ¦¬μ¦˜_λ¬Έμ œν’€μ΄ (4)
      • BOJ_λ°±μ€€ (4)
    • πŸ“‚ ν”„λ‘œκ·Έλž˜λ° (3)
    • πŸ“‚ DevOps (2)
      • 배포 (2)
    • πŸ“‚ ν›„κΈ° (8)
      • μš°μ•„ν•œ ν…Œν¬μ½”μŠ€(ν”„λ¦¬μ½”μŠ€) (4)
      • 2023λ…„ (3)
      • 2024λ…„ (1)
    • πŸ“‚ 회고 (1)
      • 2023λ…„ (1)

λΈ”λ‘œκ·Έ 메뉴

  • πŸš€ GitHub

ν‹°μŠ€ν† λ¦¬

hELLO Β· Designed By μ •μƒμš°.
Amenable

Amenable's Blog

private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν„΄μž„μ„ λ³΄μ¦ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ3)]
πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”

private μƒμ„±μžλ‚˜ μ—΄κ±° νƒ€μž…μœΌλ‘œ μ‹±κΈ€ν„΄μž„μ„ λ³΄μ¦ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ3)]

2022. 11. 27. 21:20

  ν•΄λ‹Ή μž₯μ—μ„œλŠ” 싱글턴을 λ§Œλ“œλŠ” 방식을 μ†Œκ°œν•˜κ³  μžˆλ‹€. private μƒμ„±μžλ₯Ό μ΄μš©ν•˜λŠ” 2κ°€μ§€ 방식과 μ—΄κ±° νƒ€μž…μ„ μ΄μš©ν•˜λŠ” 1κ°€μ§€ 방식, 총 3κ°€μ§€ 방식을 μ†Œκ°œν•˜κ³  μžˆλ‹€. 각각의 μž₯점과 단점에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

 

1. 'private μƒμ„±μž + public static final ν•„λ“œ'λ₯Ό μ΄μš©ν•˜λŠ” 방법

public class Elvis{

    /**
     * 싱글톀 였브젝트
     */
    public static final Elvis INSTANCE = new Elvis();
    
    private Elvis(){}
    
    public void leaveTheBuilding(){
        System.out.println("Whoa baby, I'm outta here!");
    }
    
    public void sing(){
        System.out.println("I'll hava a blue~ Christmas without you~");
    }
}

------------------------------
// μ•„λž˜λŠ” λ‹€λ₯Έ ν΄λž˜μŠ€μ— μž‘μ„±λœ 것이라고 μƒκ°ν•˜μž.
public static void main(String[] args){
    Elvis elvis = Elvis.INSTANCE;
    elvis.leaveTheBuilding();
}

  μœ„μ™€ 같이 λ§Œλ“€κ³  μ‚¬μš©ν•  수 μžˆλ‹€. μ΄κ²ƒμ˜ 'κ°„κ²°ν•˜κ³  μ‹±κΈ€ν„΄μž„μ„ API에 λ“€μ–΄λ‚Ό 수 μžˆλ‹€.'λΌλŠ” μž₯점이 μžˆλ‹€. μƒμ„±μžκ°€ private인 것을 보고 μΈμŠ€ν„΄μŠ€λ₯Ό 직접 μƒμ„±ν•˜μ§€ λͺ»ν•˜κ²Œ λ§‰μ•˜λ‹€λŠ” 것을 λ°”λ‘œ μ•Œ 수 μžˆλ‹€. 그리고 static final둜 μ„ μ–Έλœ 뢀뢄이 μžλ°”λ… 생성 μ‹œ λ³„λ„μ˜ ν•„λ“œλ‘œ 보여주기 λ•Œλ¬Έμ— 주석과 ν•¨κ»˜ μ‹±κΈ€ν„΄μž„μ„ API에 λ“œλŸ¬λ‚Ό 수 μžˆλ‹€λŠ” 것이닀. (μžλ°”λ…μ—μ„œ description에 주석이 듀어감)

  첫 번째 단점은 싱글톀을 μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ ν…ŒμŠ€νŠΈλ₯Ό ν•˜κΈ° μ–΄λ ΅λ‹€λŠ” 것이닀. μ•„λž˜μ™€ 같이 μ½˜μ„œνŠΈ 클래슀λ₯Ό ν…ŒμŠ€νŠΈν•˜λŠ” 경우 κ³„μ†ν•΄μ„œ elvisλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€λŠ” λ¬Έμ œκ°€ μžˆλ‹€. (ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ μ΄λ ‡κ²Œ λ™μž‘ν•˜λŠ” 것은 맀우 λΉ„νš¨μœ¨μ )

public class Concert{

    private boolean lightsOn;
    
    private boolean mainStateOpen;
    
    private Elvis elvis;
    
    public Concert(Elvis elvis){
        this.elvis = elvis;
    }
    
    public void perform(){
        mainStateOpen = true;
        lightsOn = true;
        elvis.sing();
    }
    
    public boolean isLightOn(){
        return LightsOn;
    }
    
    public boolean isMainStateOpen(){
        return mainStateOpen;
    }
}
class ConcertTest{
    @Test
    void perform(){
        Concert concert = new Concert(Elvis.INSTANCE); // ν•΄κ²° 방법 : new Concert(new MockElvis());
        concert.perform();
        
        assertTrue(concert.isLightsOn());
        assertTrue(concert.isMainStateOpen());
    }
}

  ν•΄κ²° 방법은 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄μ„œ κ°€μ§œ(mock)λ₯Ό μ£ΌλŠ” 것이닀. 

  두 번째 단점은 λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ private μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€λŠ” 것이닀. μ•„λž˜μ²˜λŸΌ 같은 νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μ—¬λŸ¬ 개 λ§Œλ“€ 수 μžˆλ‹€λŠ” 것이닀. 이에 λŒ€ν•œ 해결책은 flag 값을 μ΄μš©ν•˜μ—¬ 이미 μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λœ 경우 λ‹€μ‹œ μƒμ„±ν•˜λŠ” κ³Όμ •μ—μ„œ μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œν‚€λŠ” 것이닀.

public static void main(String[] args){
    try{
        Constructor<Elvis> defaultConstructor = Elvis.class.getDeclaredConstructor();
        defaultConstructor.setAccessible(true);
        Elvis elvis1 = defaultConstructor.newInstance();
        Elvis elvis2 = defaultConstructor.newInstance();
        System.out.println(elvis1 == elvis2); // false
    } catch(Exception exception){
    }
}

 

  μ„Έ 번째 단점은 역직렬화 ν•  λ•Œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€κ°€ 생길 수 μžˆλ‹€λŠ” 것이닀. λ§Œμ•½ readResolve()λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄ 싱글턴이 보μž₯λœλ‹€.(μ•„λž˜λŠ” readResolve()λ₯Ό μ •μ˜ν•˜μ§€ μ•Šμ€ μƒνƒœμ΄λ‹€.)

public class ElvisSerialization{
    public static void main(String[] args){
        // 직렬화
        // 직렬화λ₯Ό 톡해 객체 정보λ₯Ό μ–΄λ”˜κ°€μ— μ €μž₯ κ°€λŠ₯
        try(ObjectOutput out = new ObjectOutputStream(new FileOutputStream("elvis.obj"))){
            out.writeObject(Elvis.INSTANCE);
        } catch (IOException e){
            e.printStackTrace();
        }
        
        // 역직렬화
        // 역직렬화λ₯Ό 톡해 μ–΄λ”˜κ°€μ— μ €μž₯된 객체 정보λ₯Ό μ½μ–΄μ˜¬ 수 μžˆλ‹€.
        try(ObjectOutput in = new ObjectInputStream(new FileInputStream("elvis.obj"))){
            Elvis elvis3 = (Elvis) in.readObject();
            System.out.prinln(elvis3 == Elvis.INSTANCE); // false;
        } catch (IOException | ClassNotFoundException e){
            e.printStackTrace();
        }
    }
}

[정리]

μž₯점

  1. κ°„κ²°ν•˜κ³  μ‹±κΈ€ν„΄μž„μ„ API에 λ“€μ–΄λ‚Ό 수 μžˆλ‹€.

단점

  1. 싱글턴을 μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈλ₯Ό ν…ŒμŠ€νŠΈν•˜κΈ° μ–΄λ €μ›Œμ§„λ‹€.
  2. λ¦¬ν”Œλ ‰μ…˜μœΌλ‘œ private μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.
  3. 역직렬화 ν•  λ•Œ μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€κ°€ 생길 수 μžˆλ‹€.

 

2. 'private μƒμ„±μž + 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ'λ₯Ό μ΄μš©ν•˜λŠ” 방법

public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    
    private Elvis() { }
    
    public static Elvis getInstance(){
        return INSTANCE;
    }
    
    public void leaveTheBuilding(){
        System.out.println("Whoa baby, I'm outta here!");
    }
}

---------------------------
// μ•„λž˜λŠ” λ‹€λ₯Έ ν΄λž˜μŠ€μ— μž‘μ„±λœ 것이라고 μƒκ°ν•˜μž.
public static void main(String[] args){
    Elvis elvis = Elvis.getInstance();
    elvis.leaveTheBuilding();
}

    첫 번째 λ°©λ²•κ³Όμ˜ 차이점은 λ©”μ„œλ“œλ₯Ό 톡해 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€μ Έκ°„λ‹€λŠ” 점이닀. λ‹¨μ μ˜ 첫 번째 방식과 λ™μΌν•˜λ‹€. μž₯점 3가지에 λŒ€ν•΄μ„œ μ•Œμ•„λ³΄μž.

 

public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    
    private Elvis() { }
    
    public static Elvis getInstance(){
        return new Elvis(); // 바뀐 λΆ€λΆ„
    }
    
    public void leaveTheBuilding(){
        System.out.println("Whoa baby, I'm outta here!");
    }
}

  첫 번째, λ©”μ„œλ“œλ₯Ό μœ„μ™€ 같이 λ°”κΎΈκ²Œ λœλ‹€λ©΄ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ₯Ό λ°”κΎΈμ§€ μ•Šκ³ λ„ 싱글턴이 μ•„λ‹ˆκ²Œ λ°”κΏ€ 수 μžˆλ‹€.

 

public class MetaElvis<T> {
    private static final MetaElvis<Object> INSTANCE = new MetaElvis<>();
    
    private MetaElvis(){}
    
    @SuppressWarnings("unchecked")
    public static <T> MetatElvis<T> getInstance(){
        return (MetaElvis<T>) INSTANCE;
    }
    
    public void say(T t){
        System.out.println(t);
    }
    
    public void leaveTheBuilding(){
        System.out.println("Whoa baby, I'm outta here!");
    }
}

--------

public static void main(String[] args){
    MetaElvis<String> elvis1 = MetaElvis.getInstance();
    MetaElvis<Integer> elvis2 = MetaElvis.getInstance();
}

  두 번째, μ œλ„€λ¦­ νƒ€μž…μœΌλ‘œ λ™μΌν•œ μ‹±κΈ€ν„΄ μΈμŠ€ν„΄μŠ€λ₯Ό μ‚¬μš©ν•˜κ³  싢을 λ•Œ μœ„μ™€ 같이 μ œλ„€λ¦­ μ‹±κΈ€ν„΄ νŒ©ν„°λ¦¬λ₯Ό λ§Œλ“€μ–΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€. (μΈμŠ€ν„΄μŠ€λŠ” λ™μΌν•˜μ§€λ§Œ μ›ν•˜λŠ” νƒ€μž…μœΌλ‘œ λ°”κΏ”μ„œ μ‚¬μš©ν•  수 있음)

 

public Class Concert{
    public void start(Supplier<Singer> singerSupplier){
        Singer singer = singerSupplier.get();
        singer.sing();
    }
    
    public static void main(String[] args){
        Concert concert = new Concert();
        concert.start(Elvis::getInstance);
    }
}

  λ§ˆμ§€λ§‰μœΌλ‘œ μœ„μ™€ 같이 λ©”μ„œλ“œ 자체λ₯Ό supplier의 κ΅¬ν˜„μ²΄ νŒŒλΌλ―Έν„°μ— λ„˜κΈΈ 수 μžˆλ‹€.

 

[정리]

μž₯점

  1. APIλ₯Ό λ°”κΎΈμ§€ μ•Šκ³ λ„ 싱글턴이 μ•„λ‹ˆκ²Œ λ³€κ²½ν•  수 μžˆλ‹€.
  2. 정적 νŒ©ν„°λ¦¬λ₯Ό μ œλ„ˆλ¦­ μ‹±κΈ€ν„΄ νŒ©ν„°λ¦¬λ‘œ λ§Œλ“€ 수 μžˆλ‹€.
  3. 정적 νŒ©ν„°λ¦¬μ˜ λ©”μ„œλ“œ μ°Έμ‘°λ₯Ό κ³΅κΈ‰μž(Supplier)둜 μ‚¬μš©ν•  수 μžˆλ‹€.

단점

  1. 'private μƒμ„±μž + public static final ν•„λ“œ'의 3κ°€μ§€ 단점과 동일

 

3. 'μ—΄κ±° νƒ€μž…'을 μ΄μš©ν•˜λŠ” 방법

public enum Elvis{
    INSTANCE;
    
    public void leaveTheBuilding(){
        System.out.println("Whoa baby, I'm outta here!");
    }
}

----------

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

  enum으둜 μ„€μ •ν•˜κ³  INSTANCEλ₯Ό ν•˜λ‚˜ λ§Œλ“€λ©΄ 끝이닀. 이 방법은 μ•žμ—μ„œ λ‹¨μ μœΌλ‘œ λ‚˜μ˜¨ λ¦¬ν”Œλ ‰μ…˜κ³Ό 직렬화&역직렬화 λ¬Έμ œμ— λŒ€ν•΄μ„œ 맀우 μ•ˆμ „ν•˜λ‹€λŠ” 것이닀. 단점 1둜 λ‚˜μ˜¨ ν…ŒμŠ€νŠΈλ₯Ό ν•˜κΈ° μ–΄λ €μš΄ λ¬Έμ œλŠ” μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•΄μ„œ ν•΄κ²°ν•˜λ„λ‘ ν•˜μž.(μΈν„°νŽ˜μ΄μŠ€ κ΅¬ν˜„μ΄ κ°€λŠ₯ν•˜κΈ° λ•Œλ¬Έμ— ν•΄κ²° κ°€λŠ₯ν•˜λ‹€λŠ” 의미)

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

 

 

  μ΄μƒμœΌλ‘œ 1) private μƒμ„±μž + public static final ν•„λ“œ 2) private μƒμ„±μž + 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ 3) μ—΄κ±° νƒ€μž…μœΌλ‘œ 싱글턴을 λ§Œλ“œλŠ” 방식을 μ•Œμ•„λ³΄μ•˜λ‹€. 

 

ν•΄λ‹Ή 글은 λ°±κΈ°μ„  λ‹˜μ˜ 'μ΄νŽ™ν‹°λΈŒ μžλ°” μ™„λ²½ 곡랡'을 μˆ˜κ°•ν•˜κ³  μž‘μ„±ν•œ κ²ƒμž…λ‹ˆλ‹€.

'πŸ“‚ JAVA > μ΄νŽ™ν‹°λΈŒ μžλ°”' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

λΆˆν•„μš”ν•œ 객체 생성을 ν”Όν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ6)]  (0) 2022.11.29
μžμ›μ„ 직접 λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ5)]  (0) 2022.11.28
μΈμŠ€ν„΄μŠ€ν™”λ₯Ό λ§‰μœΌλ €κ±°λ“  private μƒμ„±μžλ₯Ό μ‚¬μš©ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ4)]  (0) 2022.11.28
μƒμ„±μžμ—κ²Œ λ§€κ°œλ³€μˆ˜κ°€ λ§Žλ‹€λ©΄ λΉŒλ”λ₯Ό κ³ λ €ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ2)]  (0) 2022.11.26
μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ³ λ €ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ 1)]  (0) 2022.11.26
    'πŸ“‚ JAVA/μ΄νŽ™ν‹°λΈŒ μžλ°”' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€
    • μžμ›μ„ 직접 λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ5)]
    • μΈμŠ€ν„΄μŠ€ν™”λ₯Ό λ§‰μœΌλ €κ±°λ“  private μƒμ„±μžλ₯Ό μ‚¬μš©ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ4)]
    • μƒμ„±μžμ—κ²Œ λ§€κ°œλ³€μˆ˜κ°€ λ§Žλ‹€λ©΄ λΉŒλ”λ₯Ό κ³ λ €ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ2)]
    • μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ³ λ €ν•˜λΌ - [2μž₯ 객체 생성과 파괴(μ•„μ΄ν…œ 1)]
    Amenable
    Amenable
    CS, μžλ°”, 자료ꡬ쑰, μ•Œκ³ λ¦¬μ¦˜, μŠ€ν”„λ§, μŠ€ν”„λ§ λΆ€νŠΈμ— ν•΄λ‹Ήν•˜λŠ” κ°œλ°œμ— κ΄€ν•œ λ‚΄μš©μ„ κ³΅μœ ν•©λ‹ˆλ‹€.

    ν‹°μŠ€ν† λ¦¬νˆ΄λ°”