Effective Java Ch2. 객체의 생성과 소멸 - Item 3

Donghyeok Jang·2021년 8월 21일
1

Effective Java

목록 보기
4/4

Item 3. 싱글톤의 특징을 private 생성자 또는 Enum 타입으로 적용할 것.

특정 Scope 안에서 최초 하나의 인스턴스만 만드는 클래스를 싱글톤 패턴이라고 한다. 보통 함수 같은 Stateless 객체(Item 24) 또는 본질적으로 유일한 시스템 컴포넌트들을 싱글톤 패턴으로 만든다.

예시로, 프로그램 내부에서 발생하는 이벤트를 스케줄링 하는 개체가 있다고 할 때 내부의 모든 이벤트는 하나의 스케줄링 큐에서 처리가 되어야 한다. 만약 큐가 이벤트 발생마다 생긴다면 이는 개발자의 의도와 다르게 작동하게 된다.

이렇게 객체가 단 한 개만 존재야하고 특정 Scope 내에서 해당 객체를 공유해야 할 때 사용한다.
다만, 싱글톤 패턴을 만들 때 주의해야 할 점이 멀티스레드 환경에서 두 개의 인스턴스가 생길 수도 있으니 이 점을 고려하고 코드를 작성해야 한다. 해당 Item에서 이 문제를 고려한 코드를 보여주고 있다.


final 필드

첫 번째는 final 필드로 인스턴스를 제공하는 방법이다.

public class Elivs {
	public static fianl Elvis INSTANCE = new Elvis();
    
    private Elvis() {} // client 코드에서 생성자 사용 불가
    
    // 리플렉션을 방지하기 위한 코드
    int count = 0;
    private Elvis() {
    	// 생성자 안에서 count 하거나 flag를 사용해 막을 수 있다.
        // 다만 코드가 약간 덜 클린? 하다.
    	count += 1;
        if(count != 0) {
        	throw new IllegalStateException();
        }
    }
}

리플렉션을 사용해서 private 생성자를 호출하는 방법을 제외하면 생성자는 오직 최초 한번만 호출되고 Elvis는 싱글톤이 된다.

장점

  • 이런 API 사용이 static 팩토리 메소드를 사용하는 것 보다 명확하고 간단하다.

Static 팩토리 메소드

public class Elivs {
	private static fianl Elvis INSTANCE = new Elvis();
    
    private Elvis() {} // client 코드에서 생성자 사용 불가
    
    public static Elvis getInstance() {
    	return INSTANCE;
        
        // 싱글톤을 사용하지 않고 싶을 때는 다음 코드를 사용해 간단하게 변경한다.
        // return new Elvis();
    }
}

장점

  • API를 변경하지 않고 싱글톤 사용 여부를 변경할 수 있다.
  • 이는 public final 필드를 사용한 방법에서 싱글톤을 제거했을 때 생기는 코스트(클라이언트 코드 전면 변경)보다 훨씬 가볍다.
  • 필요시 Generic 싱글톤 팩토리(Item 30)를 만들 수 있다.

Enum

직렬화/역직렬화 할 때 코딩으로 문제를 해결할 필요도 없고, 리플렉션으로 호출되는 문제도 고민하지 않아도 되는 방법이다.

public enum Elvis3 {

    INSTANCE;

    public String getName() {
        return "jdhyeok";
    }
}
public class SingleTonClient {
    public static void main(String[] args) {
        // ENUM의 인스턴스
        String name = Elvis.INSTANCE.getName();
    }
}

싱글톤을 구현하는 최선의 방법이다. 하지만 상속을 하는 상황에서는 사용할 수 없다. 가장 이상적이긴 하지만 현실에서는 해당 방법으로 구현하는 경우는 드물다고 한다.

ps. 객체 직렬화/역직렬화가 무엇인지 간단하게 찾아 봤는데 객체에 있는 정보를 json, txt, xml 등으로 변경/json, txtm xml 등의 파일을 객체로 받아와 저장하는 부분에 많이 사용되는 개념인 것 같다. 이를 통해 네트워크 통신과 같은 것을 구현하는 것으로 보인다. 추후에 자세히 알아보도록 할 것이다.

Ref.

Effective Java 3rd Edition by Joshua Bloch

백기선님 유튜브 동영상 및 자료
https://www.youtube.com/watch?v=X7RXP6EI->5E&list=PLOFN6hDJLxo0MYZd1z6GCaRdFWX3kTb6A&index=2

싱글톤 패턴이 필요한 이유와 실제 서비스에 적용까지
https://injae-kim.github.io/dev/2020/08/06/singleton-pattern-usage.html

profile
Feedback is a gift

1개의 댓글

comment-user-thumbnail
2022년 9월 3일

Feedback 드립니다^_^

답글 달기