본문 바로가기

언어/JAVA

SingleTon Pattern

싱글톤 패턴이란 인스턴스를 하나만 만들어 사용하기 위한 패턴이다. 객체지향에서 모든 객체들은 라이프 사이클을 가지고있다. 객체가 생성된고 GC에 의해 삭제되기까지가 하나의 사이클이다. 근데 객체를 여러개 만들지않고 1개만들어 이를 공유해서 쓰고싶을 때 싱글톤패턴을 사용하게된다.  싱글톤패턴을 사용하게 되면 객체생성에 대한 비용 및 데이터 공유를 쉽게 할 수있다. 대표적으로 DB의 트랜젝션을 관리하는 클래스가 그러하다.

 

싱글톤 패턴의 예제

public class Government {

    private static Government government;

    private Government()
    {
        System.out.println("직접호출 할 수 없습니다.");
    }

    public static Government election()
    {
        if(government == null)
        {
            government = new Government();
            return government;
        }
        return government;
    }
}

Government class는 생성자가 private로 직접 인스턴스를 생성할 수 없다. (Reflection 제외)

Government government = new Government() //불가능

Government class의 static 변수인 government는 private으로 외부에서 인스턴스를 주입할 수 없다.

 

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

1. 고정된 메모리 영역을 얻으면서 하나의 new로 인스턴스를 사용하기 때문에 메모리낭비를 방지한다.

2. 데이터 공유가 쉽다는 점이다. 싱글톤 인스턴스가 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근해서 사용할 수 있다. (동시성이슈가 발생할 수 있으니 주의하자.)

 

싱글톤 패턴의 문제점

1. private 생성자를 가지고 있기에 상속을 할 수 없다.

  • 자기자신만이 본인 오브젝트를 만들 수 있도록 제한하기 때문에 private 생성자를 사용했다. 하지만 이렇기 때문에 상속이 불가능하며, 이는 다형성 또한 제공할 수 없다는 뜻. 객체지향 설계를 적용할 수 없다는 것.

2. 테스트가 어렵다

  • 만들어지는 방식이 제한적이기 때문에 mock 오브젝트 등으로 대체하기 힘들다.

3. 서버환경에서는 1개의 인스턴스를 보장하지 못한다.

  • 서버에서 클래스로더를 어떻게 구성하고 있느냐에 따라서 하나이상의 instnace가 만들어질 수 있다. 따라서 java환경에서 싱글톤이 보장된다할 수 없을 수 있다.

4. 전역상태를 만들 수 있기 때문에 바람직하지 못하다.

  • Sington은 어디에서든지 누구나 접근할 수 있다. 그리고 어디든지 사용될 수 있게되기 때문에 아무 객체가 자유롭게 접근하여 수정하고 데이터를 공유할 수 있는 상태가 될 수 있다는 것이다.멀티스레딩 환경에서 발생할 수 있는 동시성 문제 해결을 위해 syncronized 키워드를 사용해야 한다.

5. 5원칙 중에 OCP와 DIP를 위반하게된다.

  • 의존 관계상 클라이언트가 구체 클래스에 의존하게 된다. new 키워드를 직접 사용하여 클래스 안에서 객체를 생성하고 있으므로, 이는 SOLID 원칙 중 DIP를 위반하게 되고 OCP 원칙 또한 위반할 가능성이 높다.

싱글톤은 장점이 명확한 만큼 단점 또한 많다. 안티패턴으로도 불려 지양되기도 한다.

하지만 스프링에서는 스프링 컨테이너(Application Context)에 의해 사용된다. 컨테이너 내에서 특정 클래스에 대해 @Bean으로 정의되면, 스프링 컨테이너는 이 클래스에 대해 한개의 인스턴스를 만들고 이 인스턴스는 설정 정보에 의해 관리되고, bean이 호출될 때마다 스프링은 생성된 공유 인스턴스를 리턴시킨다.

스프링 컨테이너는 그 어떤 호출에도단일 공유 인스턴스를 리턴시키므로 thread safety도 자동으로 보장된다.

 

 

참고

https://sabarada.tistory.com/25?category=800572

'언어 > JAVA' 카테고리의 다른 글

정적 팩터리 메서드(Static Factory Method)  (0) 2022.05.18
정적 멤버 클래스 vs 비정적 멤버 클래스  (0) 2022.02.07
strategy pattern  (0) 2022.01.22
Adapter Pattern  (0) 2022.01.21
[UML]클래스 다이어그램  (0) 2022.01.19