싱글톤(Singleton) 패턴Java2023. 3. 28. 06:33
Table of Contents
728x90
728x90
싱글톤 패턴이란?
클래스의 인스턴스가 오직 1개만 생성되는 디자인 패턴이다.
public class SingletonPattern {
private static SingletonPattern instance = new SingletonPattern();
//생성자는 private
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
return instance;
}
public void what() {
System.out.println("싱글톤패턴");
}
public static void main(String[] args) {
SingletonPattern s1 = SingletonPattern.getInstance();
}
}
장점
1. 여러 클래스에서 해당 클래스의 생성자를 호출해도 처음 생성해놓은 인스턴스를 리턴하기 때문에 메모리 낭비를 방지할 수 있다.
2. 싱글톤으로 구현한 인스턴스는 전역이다. 즉, 다른 클래스의 인스턴스들이 데이터를 공유할 수 있다.
도메인 관점에서 인스턴스가 한 개만 존재하는 것을 보증하고 싶은 경우 싱글톤 패턴을 사용하기도 한다.
단점
1. 코드 자체가 너무 길어진다
멀티스레딩 환경에서 발생할 수 있는 동시성 문제를 해결하기 위해 syncronized 키워드가 필요하다
2. 테스트하기가 어렵다.
애플리케이션 전역에서 상태를 공유하기 때문에 매번 인스턴스의 상태를 초기화시켜주어야 한다.
3. SOLID원칙 중 DIP를 위반하게되고 OCP원칙도 위반할 가능성이 높다.
의존 관계상 클라이언트가 구체 클래스에 의존하게 된다. (new 키워드를 사용한 클래스 내부 객체 생성)
4. 자식 클래스를 만들 수 없고 내부 상태를 변경하기 어렵다.
싱글톤 패턴은 안티패턴으로 불릴 만큼 단독으로 사용한다면 객체 지향에 위반되는 사례가 많다.
스프링과 같은 프레임워크에서 사용하면 단점을 보완하여 사용할 수 있다.
(스프링 빈은 기본적으로 싱글톤 스코프로 생성되고 관리된다)
@Component
public class SingletonPattern{
//싱글톤 스코프 : 프로그램에서 해당 빈의 인스턴스를 오직 하나만 생성해서 재사용하는것
//상태를 저장하지 않고 로직만 존재하는 경우(매번 객체생성이 불필요하기 때문)
}
구현방법
1. static과 synchronized
public class SingletonPattern {
private volatile static SingletonPattern instance;
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new SingletonPattern();
}
}
}
return instance;
}
}
instance가 아직 초기화되지 않았을 때만 syncronized를 호출해 쓰레드 간 동기화 오버헤드를 줄이는 방법
volatile을 이용해 재배치 문제가 생기지 않게 한다.
volatile ( 자세한 설명 : https://nesoy.github.io/articles/2018-06/Java-volatile )
volatile로 선언된 변수가 있는 코드는 최적화되지 않는다.
Read시 CPU cache에 저장된 값이 아닌 Main Memory에서 읽고, Write 시 Main Memory까지 작성하는 것
2. LasyHolder
public class SingletonPattern {
private SingletonPattern() {
}
public static SingletonPattern getInstance() {
return LazyHolder.INSTANCE;
}
private static class LazyHolder {
private static final SingletonPattern INSTANCE = new SingletonPattern();
}
}
getInstance 호출 시 LasyHolder.INSTANCE가 참조되면서 LasyHolder가 초기화되며 INSTANCE가 생성된다.
싱글톤 패턴 구현 시 추천되는 방법으로 효율적인 구현 방법이다.
728x90
300x250
@mag1c :: 꾸준히 재밌게
2023.04 ~ 백엔드 개발자의 기록
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!