tonykang22 / study

0 stars 0 forks source link

[디자인 패턴] 싱글톤 패턴 #64

Open tonykang22 opened 2 years ago

tonykang22 commented 2 years ago

싱글톤 패턴이란

인스턴스를 오직 한 개만 제공하는 클래스



싱글톤 패턴 구현 방법 1

private 생성자에 static 메소드

}


<br><br>

## 싱글톤 패턴 구현 방법 2
### 동기화 (synchronized)를 사용해 멀티쓰레드 환경에 안전하게 만드는 방법
- getInstance()를 호출할 때 마다 synchronized를 사용하기 때문에 성능이 저하된다. (lock을 주었다가 풀었다가 반복해야하기 때문이다.)
- 자바의 동기화 블럭 처리 방법은?
    * 락을 주고 푸는 방식으로 처리한다.
- getInstance() 메소드 동기화시 사용하는 락은 인스턴스의 락인가 클래스의 락인가? 이유는?
    * 클래스의 락이다. 만약 인스턴스의 락이라면, 동기화시 하나의 객체를 보장할 수 없게 되기 때문이다.
``` java
public class Settings2 {

    private static Settings2 instance;

    private Settings2() { }

    public static synchronized Settings2 getInstance() {
        if (instance == null) {
            instance = new Settings2();
        }

        return instance;
    }

}



싱글톤 패턴 구현 방법 3

이른 초기화 (eager initialization)을 사용하는 방법

}


<br>

- checked exception을 던질 때, 코드를 아래와 같이 변경할 수 있다.
``` java
public class Settings3 {

    private static Settings3 instance = null;

    static {
        try {
            instance = new Settings3();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Settings3() throws Exception { 
        throw new Exception();
    }

    public static Settings3 getInstance() {
        return instance;
    }

}



싱글톤 패턴 구현 방법 4

double checked locking으로 효율적인 동기화 블럭 만들기

}


<br><br>

## 싱글톤 패턴 구현 방법 5
### static inner 클래스를 사용하는 방법
- 스레드 세이프 하면서, lazy loading이 가능한 코드가 되는 방법
- double checked locking 보다 구현이 간단하다.
- 이 방법은 static final를 썼는데도 왜 지연 초기화 (lazy initialization)라고 볼 수 있는가?
    * Inner class는 클래스가 처음 사용되는 시점에 초기화되기 때문이다. 즉, getInstance()가 호출되는 시점에 초기화 되기 때문이라고 할 수 있다.
``` java
public class Settings5 {

    private Settings5() { }

    private static class Settings5Holder {
        private static final Settings5 INSTANCE = new Settings5();
    }

    public static Settings5 getInstance() {
        return Settings5Holder.INSTANCE;
    }

}



싱글톤 패턴 구현 깨트리는 방법 1

리플렉션을 사용한다면?



싱글톤 패턴 구현 깨트리는 방법 2

직렬화 & 역질렬화를 사용한다면?

} }


<br><br>

## 싱글톤 패턴 구현 방법 6
### enum을 사용하는 방법
- 리플렉션을 사용하는 방법에 대한 대응법이 될 수 있다.
- enum도 property나 method를 얼마든지 정의해서 사용할 수 있다. (생성자는 기본이 private)
- enum 타입의 인스턴스를 리플렉션을 만들 수 있는가?
    * enum 타입은 리플랙션을 할 수 없도록 막혀있기 때문에 리플랙션에 안전하다.
- enum으로 싱글톤 타입을 구현할 때의 단점은?
    * 클래스가 메모리에 할당되는 시점에 인스턴스가 미리 만들어진다. (eager initialization) 초기화 시점이 문제가 되지 않다면 가장 안전한 방법이다.
    * enum은 상속이 불가능하다.
- 직렬화 & 역직렬화 시에 별도로 구현해야 하는 메소드가 있는가?
    * enum 타입은 enum 클래스를 상속받게 되는데, enum 클래스는 Serializable을 이미 구현하고 있기 때문에 추가적인 구현이 필요 없다.
``` java
public enum Settings5 {

    INSTANCE;

}



싱글톤 패턴 복습

직접 말하며 설명하고 코딩해보자



싱글톤 패턴

실무에서는 어떻게 쓰이나?