[Design Pattern] Singleton Pattern

Gavin Ariel Lee·2021년 10월 15일
0

Singleton Pattern

객체를 하나만 생성하도록 하며, 생성된 객체를 어디서든지 참조할 수 있도록 하는 패턴
생성 패턴 중 하나

생성 방법

static block

static 블럭 사용시 클래스가 로딩될 때 한번만 실행
인스턴스가 사용되는 시점이 아닌 로딩 시점에 실행된다.

public class Singleton {
	private static Singleton singleton;
    
	private Singleton() {
   	}
    
    static {
    	try {
        	singleton = new Singleton();
        } catch(Exception e){
        	...
        }
        
    }

	public static Singleton getInstance() {
    		return singleton;
	}
}

lazy init

static 방법을 개선하여 클래스 로딩 시점이 아닌 인스턴스가 필요하여 요청시 생성
→ 특정 쓰레가 동시에 getInstance 호출시 인스턴스가 두번 생성되는 문제 발생

public class Singleton {
	private static Singleton singleton;
    
	private Singleton() {
   	}

	public static Singleton getInstance() {
    		if(instance == null) {
            		singleton = new Singleton();
            	}
    		return singleton;
	}
}

Thread safe + lazy

synchronized 키워드를 붙임으로서 쓰레드 동시 접근 문제 해결 → synchronized는 성능 저하 발생시킴

public class Singleton {
	private static Singleton singleton;
    
	private Singleton() {
   	}

	public static synchronized Singleton getInstance() {
    		if(instance == null) {
            		singleton = new Singleton();
            	}
    		return singleton;
	}
}

Holder

java에서 signleton 생성에 사용하는 대표적인 방법
JVM의 클래스 로더 메커니즘과 클래스의 로드 시점을 이용하여 내부 클래스를 통해 생성 시킴으로써 쓰레드 간의 동기화 문제를 해결

public class Singleton {
    
	private Singleton() {
   	}
    
    	private static class InnerInstanceClass(){
    		private static final Singleton singleton = new Singleton();
    	}

	public static Singleton getInstance() {
    		return instance;
	}
}

사용하는 이유

  • 메모리 낭비 방지
    최초 한번의 new 연산자를 통해 고정된 메모리 영역을 사용
    → 추후 해당 객체에 접근할때 메모리 낭비 방지 가능
    이미 생성된 인스턴스를 사용하므로 속도 측면에서도 좋음

  • 쉬운 데이터 공유
    전역으로 사용되는 인스턴스 이기때문에 다른 클래스에서 접근하여 사용 가능
    단, 여러 클래스에서 동시 접근시 동시성 문제 발생 가능

문제점

  • 많은 코드양
    싱글톤 패턴 적용을 위해 구현하는 코드 양이 많다.
    정적 팩토리 메서드에서 객체 생성 확인 후 생성자를 호출하는 경우 멀티스레딩-동시성 문제 해결을 위해 syncronized 사용

  • 어려운 테스트
    자원을 공유하고 있기때문에 테스트가 격리된 환경에서 수행되려면 매번 인스턴스 상태를 초기화 시켜줘야함

  • 클라이언트가 구체 클래스에 의존
    new 키워드를 직접 사용하여 클래스안에서 객체를 생성하므로 객체 지향 설계 원칙인 OPC(개방 폐쇄 원칙), DIP(의존 역전 원칙) 위반할 가능성이 있다.

이 외에도 자식 클래스 생성 불가능, 내부 상태 변경 어려움 등 문제 존재
유연성이 많이 떨어지는 패턴

profile
As you wish

0개의 댓글