Skip to content

Latest commit

 

History

History
97 lines (73 loc) · 3.52 KB

03.Enum(열거타입) 방식, 또는 PRIVATE 생성자로서 인스턴스가 오직 하나뿐인 싱글턴임을 보증하라.md

File metadata and controls

97 lines (73 loc) · 3.52 KB

싱글턴 패턴이란?

싱글턴(Singleton) : 인스턴스를 오직 하나만 생성할 수 있는 클래스

ex) 함수(무상태 객체), 설계상 유일해야 하는 시스템 컴포넌트

  • 장점
    • 고정된 메모리 영역을 얻으면서 한 번의 new로 인스턴스를 공유하기 때문에 메모리 낭비를 방지할 수 있다.
    • 두 번째 사용부터는 객체 로딩 시간이 줄어들어 성능이 좋아진다.
  • 단점
    • 싱글턴 인스턴스가 너무 많은 일을 하면 인스턴스의 간의 결합도가 높아진다. (OCP(Open-Closed Principle, 개방 폐쇄 원칙) 의 원칙에 위배 )
    • 디버깅이 어려움이 있다.
    • 테스트 코드의 작성의 어려움이 있다.

싱글턴을 만드는 방법

1. public static final 필드 방식

: 싱글턴 인스턴스를 public static final 필드로 만들고, 생성자를 private 하게 지정하여 외부에서 기본 생성자를 생성할 수 없도록 만드는 방식.

장점 : 싱글턴임이 API에 명백히 드러남, 간결함

다만, Java Reflection API 를 이용하면 싱글톤이더라도 객체를 생성해낼 수 있다.

→ 이를 방어하기 위해 방어코드를 추가로 작성한다.

```java
class Car {
    public static final Car INSTANCE = new Car ();
    private Car() {
            //  private한 생성자에서 두번째 객체가 만들어지는 것을 방지.
            if(INSTANCE != null){
                throw new RuntimeException("이미 생성된 싱글톤 객체가 존재합니다.")
            }
        } 
}

...

@Test
@DisplayName("두 객체가 같은 인스턴스를 참조함")
public void CarSameTest(){
//        Car item1 = new Car();
    Car item2 = Car.INSTANCE;
    Car item3 = Car.INSTANCE;
    assertThat(item2).isEqualTo(item3);
}

// 해당 테스트에서는 기본적으로 두 객체가 같다고 나온다.
```

2. 정적 팩터리 방식

: 아이템 1의 정적 팩터리 메서드를 public하게 만들어 싱글톤을 반환한다.

  • 장점
    • API를 바꾸지 않고도 싱글턴이 아니게 변경할 수 있다.
    • 정적 팩터리를 제네릭 싱글턴 팩터리로 만들어 타입에 유연하게 대처할 수 있다.
    • 정적팩터리의 메서드 참조를 공급자로 사용할 수 있다.

→ 다만, 이러한 장점들이 굳이 필요하지 않다면, public 필드 방식이 좋다.

```java
class Car {
    public static final Car INSTANCE = new Car ();
    private Car () {
        if(INSTANCE != null){
            throw new RuntimeException("이미 생성된 싱글톤 객체가 존재합니다.");
        }
    }
    // 정적 팩터리 방식의 싱글턴.
    public static Car getInstance(){
        return INSTANCE;
    }
}

@Test
@DisplayName("인스턴스가 전체 시스템에서 하나뿐임이 보장된다.")
public void singleton() {
    Car instance1 = Car.getInstance();
    Car instance2 = Car.getInstance();

    assertThat(instance1).isEqualTo(instance2);
}
```

3. Enum 방식- 바람직한 방법!

: public 필드 방식과 비슷하지만, 더 간결하며, 제2의 인스턴스가 만들어지는 것을 완벽히 막을 수 있다.

대부분의 상황에서는 원소가 하나뿐인 Enum 타입이 싱글턴을 만드는 가장 좋은 방식이다.

```java
public enum Car{
    INSTANCE;

}
```