프로그래밍/Java

[Java, 자바] 싱글톤 패턴(Singleton Pattern)이란 ?

차나니 2024. 4. 15. 19:00

싱글톤 패턴이란 ?

싱글톤 패턴은 객체 지향 프로그래밍에서 특정 클래스가 단 하나만의 인스턴스를 생성하여 사용하기 위한 패턴입니다.

생성자를 여러번 호출하더라도 인스턴스가 하나만 존재하도록 보장하여 애플리케이션에서 동일한 인스턴스에 접근할 수 있도록 해줍니다 !

 

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

커넥션 풀, 스레드 풀, 디바이스 설정 객체 등과 같은 경우 인스턴스를 여러 개 만들게 되면 불필요한 자원을 사용하게 되고, 프로그램이 예상치 못한 결과를 낳을 수 있습니다. 따라서 객체를 필요할 때마다 생성하는 것이 아닌 단 한 번만 생성하여 전역에서 이를 공유하고 사용할 수 있게 하기 위해 싱글톤 패턴을 사용합니다 !

 

싱글톤 패턴의 장단점

장점

유일한 인스턴스

싱글톤 패턴이 적용된 클래스의 인스턴스는 애플리케이션 전역에서 단 하나만 존재하도록 보장한다. 이는 객체의 일관된 상태를 유지하고 전역에서 접근 가능하도록 합니다.

메모리 절약

인스턴스가 단 하나뿐이므로 메모리를 절약할 수 있습니다. 생성자를 여러 번 호출하더라도 새로운 인스턴스를 생성하지 않아 메모리 점유 및 해제에 대한 오버헤드를 줄인다.

지연 초기화

인스턴스가 실제로 사용되는 시점에 생성하여 초기 비용을 줄일 수 있습니다.

 

단점 

결합도 증가

싱글톤 패턴은 전역에서 접근을 허용하기 때문에 해당 인스턴스에 의존하는 경우 결합도가 증가할 수 있습니다.

테스트 복잡성

싱글톤 패턴은 단 하나의 인스턴스만을 생성하고 자원을 공유하기 때문에 싱글톤 클래스를 의존하는 클래스는 결합도 증가로 인해 테스트가 어려울 수 있습니다.

상태 관리의 어려움

만약, 싱글톤 클래스가 상태를 가지고 있는 경우 전역에서 사용되어 변경될 수 있습니다. 이로 인해 예사이 못한 동작이 발생할 수 있습니다.

전역에서 접근 가능

애플리케이션 내 어디서든 접근이 가능한 경우, 무분별한 사용을 막기 힘듭니다. 이로 인해 변경에 대한 복잡성이 증가할 수 있습니다.

 

싱글톤 패턴의 기본 구현

싱글톤 패턴을 적용할 경우 두 개 이상의 객체는 존재할 수 없습니다. 이를 구현하기 위해서는 객체 생성을 위한  new 생성자에 제약을 걸여야하고, 만들어진 단일 객체를 반환할 수 있는 메서드가 필요합니다. 따라서 다음 세가지 조건이 반드시 충족되어야합니다.

  • new 키워드를 사용할 수 없도록 생성자에 private 접근 제어자를 지정해야합니다.
  • 유일한 단일 객체를 반환할 수 있는 정적 메서드가 필요합니다.
  • 유일한 단일 객체를 참조할 정적 참조 변수가 필요합니다.

아래 이미지는 싱글톤 패턴의 구조입니다 !

  • 클라이언트는 getInstance() 메서드를 통해 싱글톤 인스턴스를 얻을 수 있습니다.
  • getInstance() 메서드 내부에서는 instance가 null이면 생성하고, null이 아니면 instance를 반환합니다.
  • 이로써 단 하나만의 객체를 생성하여 사용할 수 있도록합니다.

싱글톤 패턴 사용 예시

싱글톤 클래스 생성

public class CompanyInfo 
{
    private static CompanyInfo innstance;
 
    private String companyName;
    private String companyAddr;
    
    
    private CompanyInfo() { }
    
    public static CompanyInfo getInstance()
    {
        if (innstance == null)
        {
            synchronized(CompanyInfo.class)
            {
                innstance = new CompanyInfo();
            }
        }
        
        return innstance;
    }
    
    
    // getter, setter 
    public String getCompanyName() {
        return companyName;
    }
 
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
 
    public String getCompanyAddr() {
        return companyAddr;
    }
 
    public void setCompanyAddr(String companyAddr) {
        this.companyAddr = companyAddr;
    }    
}

getInstance 호출

외부에서 호출 시 new를 사용하지 않고 getInstance를 사용하여 객체를 생성하거나 반환받습니다.

CompanyInfo companyInfo = CompanyInfo.getInstance();

 

Spring 싱글톤 컨테이너(스프링 컨테이너)

스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도, 객체 인스턴스를 싱글톤으로 관리해줍니다 ! 그래서 스프링 컨테이너는 싱글톤 패턴의 문제점을 해결하면서, 객체 인스턴스를 싱글톤으로 관리합니다.

Spring과 Spring Boot를 통해 사용한 빈이 바로 싱글톤 패턴으로 관리되는 빈입니다 !! 알고쓰면 좋겠죠 !?