코드 저장소.

[디자인 패턴] 싱글톤 패턴 본문

ComputerScience/디자인 패턴

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

slown 2024. 5. 16. 16:58

목차

1. 싱글톤 패턴?

2. 싱글톤 패턴의 장단점

3. 예시

 

1.싱글톤 패턴?

싱글톤 패턴은 어떤 클래스가 최대 한 번만 인스턴스화(Instance)될 수 있도록 보장하는 패턴입니다. 이는 해당 클래스의 인스턴스를 어디서든지 공유하고 접근할 수 있도록 하며, 전역 상태를 관리하거나 유일한 자원에 접근할 때 유용하게 활용됩니다. 싱글톤 패턴에 사용되는 예는 데이터베이스의 연결, 로깅, 공통설정 클래스 등이 있습니다.

 

2.싱글톤 패턴의 장단점

싱글톤 패턴의 장단점은 다음과 같습니다. 

 

장점


유일한 인스턴스 : 싱글톤 패턴이 적용된 클래스의 인스턴스는 애플리케이션 전역에서 단 하나만 존재하도록 보장합니다. 이는 객체의 일관된 상태를 유지하고 전역에서 접근 가능하도록 합니다.
메모리 절약 : 인스턴스가 단 하나뿐이므로 메모리를 절약할 수 있습니다. 생성자를 여러 번 호출하더라도 새로운 인스턴스를 생성하지 않아 메모리 점유 및 해제에 대한 오버헤드를 줄일수 있습니다.
지연 초기화 : 인스턴스가 실제로 사용되는 시점에 생성하여 초기 비용을 줄일 수 있습니다.

단점

결합도 증가 : 싱글톤 패턴은 전역에서 접근을 허용하기 때문에 해당 인스턴스에 의존하는 경우 결합도가 증가할 수 있습니다.
테스트 복잡성 : 싱글톤 패턴은 단 하나의 인스턴스만을 생성하고 자원을 공유하기 때문에 싱글톤 클래스를 의존하는 클래스는 결합도 증가로 인해 테스트가 어려울 수 있습니다.
상태 관리의 어려움 : 만약, 싱글톤 클래스가 상태를 가지고 있는 경우 전역에서 사용되어 변경될 수 있다. 이로 인해 예상치 못한 동작이 발생할 수 있습니다.
전역에서 접근 가능 : 애플리케이션 내 어디서든 접근이 가능한 경우, 무분별한 사용을 막기 힘들다. 이로 인해 변경에 대한 복잡성이 증가할 수 있습니다.

 

3. 예제

public class SingleTonExample {
	
    private static SingleTonExample example;
	
    private SingleTonExample() {
		
	}
	
    public static SingleTonExample getInstance() {
		if(example == null) {
			example = new SingleTonExample();
		}
		return example;
	}
}

 

 

위의 코드를 설명하면 다음과 같다.

  • example은 단일 객체를 저장하기 위한 정적 참조 변수입니다.
  • 외부에서는 해당 객체를 생성할 수 없도록 생성자를 private로 지정한다.
  • getInstance() 메서드를 통해 인스턴스를 얻을 수 있다.
  • getInstance()를 최초로 실행할 때에만 초기화한다. (지연 초기화)
public class Client {
	
	public static void main(String[] args) {
		
		SingleTonExample example1 = SingleTonExample.getInstance();
		SingleTonExample example2 = SingleTonExample.getInstance();
		SingleTonExample example3 = SingleTonExample.getInstance();
		
		System.out.println(example1);
		System.out.println(example2);
		System.out.println(example3);
		
		System.out.println(example1 == example2);
		System.out.println(example1 == example3);
	}
}

 

Client 클래스를 실행을 하면 싱글톤 객체를 getInstance()를 통해서 여러 변수에서 호출을 하더라도 같은 인스턴스를 참조한다.

 

여기까지가 싱글톤 패턴의 기본적인 구현입니다. 여기에서 주목을 해야되는 점은 기본생성자를 private 를 사용하여 생성을 불가능하게 하고 getInstance를 통해서만 생성이 가능합니다. getInstance는 내부적으로 생성되지 않았다면 생성하고, 기존에 생성된 값이 존재한다면 생성된 인스턴스를 리턴하는 형태로 프로그램 전반에 걸쳐 하나의 인스턴스를 유지합니다.

 

하지만 이러한 싱글톤 패턴에도 문제점은 있습니다.

 

멀티 스레드 환경에서 Thread Safe하지 않는 문제점입니다. Thread Safe는 여러 스레드가 동시에 접근하는 경우 해당 애플리케이션에 어떠한 문제도 발생하지 않는 것을 의미합니다. 즉, 싱글톤 패턴은 여러 스레드가 동시에 접근하는 경우 문제가 발생한다는 것을 의미합니다.

 

이를 해결하기 위해서 여러가지의 방법은 다음과 같습니다.

  • synchronized를 사용한 방법
  • duoble checked locking를 사용한 방법
  • Bill Pugh Solution를 사용한 방법

synchronized를 사용한 방법

public class SingleTonExample {
	
	private static SingleTonExample example;
	
	private SingleTonExample() {
		
	}
	
	public static SingleTonExample getInstance() {
		
		synchronized (SingleTonExample.class) {
			if(example == null) {
				example = new SingleTonExample();
			}
		}
		return example;
	}
}

 

Thread Safe에서 가장 단순한 방법으로 synchronized키워드를 넣어서 하나의 스레드만 접근하도록 하는 방식이다. 

하지만 단점이 있다면 여러 스레드가 동시에 접근을 할때 Lock때문에 성능이 저하가 된다.

 

duble checked locking을 사용한 방법

public class SingleTonExample {
	
	private static SingleTonExample example;
	
	private SingleTonExample() {
		
	}
	
	public static SingleTonExample getInstance() {
		if(example == null) {
			synchronized (SingleTonExample.class) {
				if(example == null) {
					example = new SingleTonExample();
				}
			}
		}
		return example;
	}
}

 

이 방법은 최초 getInstance() 메서드를 호출할 때 두 스레드가 if 문에 진입하더라도, 이후에 진행되는 synchronized 키워드로 인해 두 번째 if 문에서는 lock이 걸려 Thread Safe한 싱글톤 패턴의 구현 방법이다.

 

Bill Pugh Solution을 사용한 방법

public class SingleTonExample {
	
	private SingleTonExample() {
		
	}
	
	private static class SingletonHolder {
		private static final SingleTonExample EXAMPLE = new SingleTonExample();
	}
	
	public static SingleTonExample getInstance() {
		return SingletonHolder.EXAMPLE;
	}
}

 

private static inner class를 사용하여 Thread Safe한 싱글톤 패턴을 구현하는 방법이다. JVM의 ClassLoader에 의해서 로드될 때 내부적으로 실행되는 synchronized 키워드를 이용하는 방법이다.

 

 

'ComputerScience > 디자인 패턴' 카테고리의 다른 글

[디자인 패턴] 데코레이트 패턴  (0) 2024.06.05
[디자인 패턴] 브릿지 패턴  (0) 2024.06.03
[디자인 패턴] 어뎁터 패턴  (0) 2024.05.25
[디자인 패턴] 프록시 패턴  (0) 2024.05.21
디자인 패턴  (0) 2024.05.12