본문으로 바로가기
반응형

 

 

 

● 싱글톤 패턴이란?  

 

 

 

쉽게 말해 객체 인스턴스가 단 하나만 존재해야 하는 패턴이다.

 

 

생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 

최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 

 

 

이와 같은 디자인 유형을 싱글턴 패턴이라고 한다.

 

 

 

 

 

 

 


● 웹 애플리케이션과 싱글톤  

 

 

 

 

웹 애플리케이션은 특정한 목적이 아닌 경우,

여러 고객이 동시에 서비스를 요청한다. (ex. 여러 사용자가 같은 페이지 동시 클릭)

 

 

만약 싱글톤 패턴이 아닌 고객의 요청마다 새로운 객체를 생성한다면,

서버 자원의 소모가 매우 심할 것이다.

 

 

그렇기 때문에 웹 애플리케이션을 개발할 때,

우리가 생성할 객체(ex.여러 사용자에게 공유되는 service 등)는 

싱글톤 패턴을 적용하여 작성하여야 한다.

 

 

 

 

 

 

 

 

 


● 싱글톤 패턴을 적용하지 않은 순수 DI 컨테이너  

 

 

 

 

 

싱글톤 패턴을 적용하지 않고 service를 여러 번 호출할 시,

매번 다른 service 객체가 생성되는지 테스트해보려고 한다.

 

 

 

 

 

 

SingletonTest.java

package hello.core.singleton;

import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static org.assertj.core.api.Assertions.*;

public class SingletonTest {

    @Test
    @DisplayName("스프링 없는 순수한 DI 컨테이너")
    void pureContainer() {
        AppConfig appConfig = new AppConfig();
        // 1. 조회: 호출할 때 마다 객체를 생성
        MemberService memberService1 = appConfig.memberService();

        // 2. 조회: 호출할 때 마다 객체를 생성
        MemberService memberService2 = appConfig.memberService();

        // 참조값이 다른 것을 확인
        System.out.println("memberService1 = " + memberService1);
        System.out.println("memberService2 = " + memberService2);

        // memberService1 != memberService2
        assertThat(memberService1).isNotSameAs(memberService2);
    }

}

 

 

AppConfig에 있는 memberService 객체를 2개 생성했다.

 

이것이 다른지 확인하기 위해 테스트 코드를 작성했다.

 

 

 

※ AppConfig에 작성 정보는 아래 링크에 있다.

https://healthdevelop.tistory.com/entry/spring33

 

 

 

 

 

 

 

결과는,

 

 

 

 

 

 

다른 참조값(=다른 객체)이 나오는 것을 볼 수 있다.

 

 

 

 

 

 

 

 

 


● 싱글톤 패턴 예시

 

 

 

 

 

싱글톤 패턴의 예시를 테스트 코드로 작성해보고자 한다.

 

 

 

먼저 SingletonService를 예시로 작성하였다.

 

 

 

 

 

SingletonService.java

package hello.core.singleton;

public class SingletonService {

    // 자기 자신을 static으로 선언하면 클래스 레벨에 올라가기 때문에 딱 하나만 생성됨
    private static final SingletonService instance = new SingletonService();

    public static SingletonService getInstance() {
        return instance;
    }

    // 외부에서 SingletonService를 생성하지 못하게(위에서 자기 자신을 하나만 생성함)
    private SingletonService() {

    }

    public void logic() {
        System.out.println("싱글톤 객체 로직 호출");
    }
}

 

 

주석에 설명을 참조하면 된다.

 

 

 

정리하면,

 

 

1. static 영역에 객체 instance를 미리 하나 생성해서 올려둔다.

 

2. 이 객체 인스턴스가 필요하면 오직 getInstance() 메서드를 통해서만 조회할 수 있다.

   이 메서드를 호출하면 항상 같은 인스턴스를 반환한다.

 

3. 딱 1개의 객체 인스턴스만 존재해야 하므로, 생성자를 private으로 막아서

   혹시라도 외부에서 new 키워드로 객체 인스턴스가 생성되는 것을 막는다

 

 

 

 

 

 

 

 

 

이제 싱글톤 패턴을 사용하는 테스트 코드를 보자.

 

 

 

 

 

SingletonTest.java

package hello.core.singleton;

import hello.core.AppConfig;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import static org.assertj.core.api.Assertions.*;

public class SingletonTest {

    @Test
    @DisplayName("싱글톤 패턴을 적용한 객체 사용")
    void singletonServiceTest() {
        SingletonService singletonService1 = SingletonService.getInstance();
        SingletonService singletonService2 = SingletonService.getInstance();

        System.out.println("singletonService1 = " + singletonService1);
        System.out.println("singletonService2 = " + singletonService2);

        assertThat(singletonService1).isSameAs(singletonService2);
    }
}

 

 

위에서 생성한 singletonService 객체를 2개 생성하고

같은 객체를 반환하는지 확인해보자.

 

 

 

 

결과는,,

 

 

 

 

 

 

호출할 때마다 같은 객체 인스턴스를 반환하는 것을 확인할 수 있다.

 

 

 

 


 

 

 

싱글톤 패턴을 적용하면

 

 

고객의 요청이 올 때마다 객체를 생성하는 것이 아니라,

이미 만들어진 객체를 공유해서 효율적으로 사용할 수 있다.

 

 

 

 

 

 

반응형