이것저것

Effective Java [아이템 3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라] 본문

Effective Java

Effective Java [아이템 3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라]

nays111 2021. 4. 17. 21:51

Effective Java [아이템 3 : private 생성자나 열거 타입으로 싱글턴임을 보증하라]


싱글턴 (Singleton) 이란? : 생성자가 여러번 호출되더라도 실제로 생성되는 객체는 하나이고, 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴
ex) 함수와 같은 무상태(stateless) 객체나 설계상 유일해야하는 시스템 컴포넌트, DBCP

싱클턴 패턴 장점

- 한 번의 객체 생성으로 재사용 가능하므로 메모리 낭비 방지

- 전역성을 갖기 때문에 다른 객체와 공유 용이

 

싱글턴 패턴 단점 

- 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기 어렵다. (타입을 interface로 정의한 다음 그 interface를 구현해 만든 싱글턴이 아니라면 싱글턴 인스턴스를 가짜 구현 (mock)으로 대체 불가)

 


싱글턴을 만드는 방식 2가지

1. public static final 필드 방식의 싱글턴

public class Elvis{
	public static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    
    public void leaveTheBuilding(){...}
}

- 생성자는 private 으로 감쳐두고, 유일한 인스턴스에 접근할 수 있는 수단으로 public static 멤버 마련

- private 생성자는 Elvis.INTANCE를 초기활할 때 딱 한 번만 호출

- 장점 : 해당 클래스가 싱글턴임이 명백히 확인 가능, 간결

 

2. 정적 팩터리 메서드 방식의 싱글턴

public class Elvis{
	private static final Elvis INSTANCE = new Elvis();
    private Elvis(){...}
    public static Elvis getInstance(){return INSTANCE;}
    
    public void leaveTheBuilding({...})
}

- Elvis.getInstance는 항상 같은 객체의 참조를 반환 => 제 2의 Elvis 인스턴스 생성 X

- 장점 : API를 바꾸지 않고도 싱글턴이 아니게 변경 가능, 정적 팩터리를 제네릭 싱글턴 팩터리로 생성 가능

 

3. 열거 타입 방식의 싱글턴 (바람직한 방법)

public enum Elvis{
	INSTANCE;
    public void leaveTheBuilding(){...}
   }

- 아주 복잡한 직렬화 상황이나, 리플렉션 공격에서도 제2의 인스턴스 생성 방지 가능

- 대부분 상황에서는 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법

Comments