싱글톤 패턴

강우엉·2024년 1월 25일
0

study

목록 보기
43/44

💡 싱글톤 패턴이란?

싱글톤 패턴은 특정 클래스의 인스턴스가 오로지 1개만 생성되도록 하는 디자인 패턴이다. 즉, 생성자를 통해 여러번 호출되더라도 처음에 만들어놓은 인스턴스가 계속 사용된다.

public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
        // 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
    }

    public static Singleton getInstance() {
        return instance;
    }

    public void say() {
        System.out.println("hi, there");
    }
}

💡 싱글톤 패턴을 사용하는 이유

  • 메모리 낭비 방지
    • 최초 한번의 new를 통해 생성된 메모리 영역을 계속 사용하기에 불필요한 메모리 사용을 줄일 수 있다.
  • 자원 공유
    • 여러 부분에서 공통된 자원을 접근해야 할 때 하나의 인스턴스로 관리할 수 있다. (설정 정보, 데이터베이스 연결 등)

💡 싱글톤 패턴 사용시 주의할 점

1. 구현하는 코드가 많아진다.

위에 코드같이 단순한 방법 외에도 정적 팩토리 메서드를 사용하여 객체를 생성하고, 생성자를 호출하는 경우에 동시성 문제를 대비해 synchronized 키워드를 사용해야한다.

정적 팩토리 메서드는 객체 생성을 캡슐화하는 메서드를 말하는데, 이 메서드를 통해 객체를 생성하면 캐싱하거나 추가적인 동작을 수행할 수 있다. 하지만 이렇게 객체 생성과 동시성을 다루는 부분에서 문제가 발생할 수 있기에 synchronized 키워드를 사용하여 동기화 처리를 해주어야한다.

멀티스레드 환경에서 여러 스레드가 동시에 싱글톤 객체를 생성하려고 할 때, 객체의 일관성을 보장하기 위해 동기화가 필요하기 때문이다.

public class SharedResource {
    private static SharedResource instance;

    // private 생성자로 외부에서 인스턴스를 직접 생성하지 못하도록 함
    private SharedResource() {
    }

    // 정적 팩토리 메서드를 통해 싱글톤 인스턴스 반환
    public static synchronized SharedResource getInstance() {
        if (instance == null) {
            instance = new SharedResource();
        }
        return instance;
    }

    // synchronized를 사용하여 메서드를 동기화
    public synchronized void performOperation() {
        // 여러 스레드가 이 메서드를 동시에 호출할 수 없도록 보장
        // 메서드 내용 작성
    }
}

2. 의존성이 높아진다.

싱글톤 패턴을 사용하면 객체를 미리 생성해놓고 필요할 때 정적 메서드를 사용해야하기에 클래스 사이에 의존성이 높아진다.

싱글톤 객체를 수정해야하면 인스턴스를 참조하는 모든 클래스의 코드를 수정해야한다.

3. 테스트하기 어려워진다.

서로 독립된 환경에서 이루어지는 단위테스트를 할 때 문제가 생긴다.

하나의 인스턴스를 전역적으로 공유하고 있기 때문에 테스트에 문제가 생긴다.
따라서 매 테스트마다 인스턴스를 초기화해줘야하는 번거로움이 생긴다.

💡 스프링에서 싱글톤을 사용하는 이유

Java로 기본적인 싱글톤 패턴을 사용하려면 여러가지 문제점들이 발생한다.

  • 구현하는 코드 증가
  • 테스트코드 작성 어려움
  • 클래스간의 의존성 증가

하지만 Spring에서 싱글톤을 사용하면 이러한 문제점들을 보완해준다.

스프링에서 등록된 빈은 기본적으로 싱글톤으로 관리된다. 당연히 빈을 여러번 요청하더라도 항상 같은 객체를 돌려준다. 기본적으로 빈을 싱글톤으로 관리하는 이유는 대규모 트래픽을 처리할 수 있기 위함이다.

만약 싱글톤을 사용하지 않는 상황을 생각해보자.
클라이언트에서 요청이 올 때마다 각 로직을 처리하는 빈이 새로 생성된다면 요청이 올 때마다 많은 객체들이 생성이 될 것이다. 이러한 현상은 당연히 트래픽의 부하가 걸릴 수 있다.

📌 싱글톤 레지스트리

스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공한다.
그것이 싱글톤 레지스트리이다.

싱글톤 레지스트리를 사용하면 static 메소드나 private 생성자 등을 사용하지 않기에 더 객체지향적인 개발이 가능해진다.

위에서 말한 멀티스레드 환경에서의 동시성 문제도 해결해준다.

💡 결론

싱글톤 패턴은 안티패턴이라고도 불릴만큼 문제점이 많은 패턴이다.
항상 trade-off를 생각하고 스프링 프레임워크 등을 활용하여 안전하게 사용하는것이 바람직하다.

Reference

profile
우엉이의 코딩 성장일기💻

0개의 댓글