티스토리 뷰

나의 공부방

[디자인 패턴] 싱글톤이 안티 패턴이 될 수 있는 이유와 자바 싱글톤과 스프링 싱글톤의 차이

망나니개발자 2021. 5. 14. 19:57
반응형

 

 

1. 싱글톤이 안티 패턴이 될 수 있는 이유


[ 싱글톤이 안티 패턴이 될 수 있는 이유 ]

우리는 싱글톤패턴을 구현할 때 다음과 같이 구현을 한다. 다음은 자바 언어를 이용해 싱글톤 패턴을 구현하는 전형적인 코드이다.

public class Person {

    private static Person instance;

    private Person() {
        throw new IllegalStateException("Private Constructor");
    }

    public static Person getInstance() {
        if (instance == null) {
            instance = new Person();
        }
        return instance;
    }
}

 

 

싱글톤 패턴은 전역 상태(Global State)로 이용할 수 있다는 장점이 있지만 다음과 같은 문제점을 가지고 있어 안티 패턴으로도 많이 불린다.

 

  • private 생성자를 갖고 있어 상속이 불가능하다.
  • 테스트하기 힘들다.
  • 서버 환경에서는 싱글톤이 1개만 생성됨을 보장하지 못한다.
  • 전역 상태를 만들 수 있기 때문에 바람직하지 못하다.

 

 

 

 

1. private 생성자를 갖고 있어 상속이 불가능하다.

싱글톤은 자신만이 객체를 생성할 수 있도록 생성자를 private으로 제한한다. 하지만 상속을 통해 다형성을 적용하기 위해서는 다른 기본생성자가 필요하므로 객체지향의 장점을 적용할 수 없다. 또한 싱글톤을 구현하기 위해서는 객체지향적이지 못한 static 필드와 static 메소드를 사용해야 한다.

 

 

2. 테스트하기 힘들다.

싱글톤은 테스트하기가 힘드며 테스트 방법에 따라 불가능할 수 있다. 싱글톤은 생성 방식이 제한적이기 때문에 Mock 객체로 대체하기가 어려우며, 동적으로 객체를 주입하기도 힘들다.

테스트는 개발의 핵심인데, 테스트 코드를 작성할 수 없다는 것은 큰 단점이 된다.

 

 

3. 서버 환경에서는 싱글톤이 1개만 생성됨을 보장하지 못한다.

서버에서 클래스 로더를 어떻게 구성하느냐에 따라 싱글톤 클래스임에도 불구하고 1개 이상의 객체가 만들어질 수 있다. 따라서 Java 언어를 이용한 싱글톤 기법은 서버 환경에서 싱글톤이 꼭 보장된다고 볼 수 없다. 또한 여러 개의 JVM에 분산돼서 설치되는 경우에도 독립적으로 객체가 생성된다.

 

 

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

싱글톤의 스태틱 메소드를 이용하면 언제든지 해당 객체를 사용할 수 있고, 전역 상태(Global State)로 사용되기 쉽다. 아무 객체나 자유롭게 접근하고 수정하며 공유되는 전역 상태는 객체지향 프로그래밍에서 권장되지 않는다.

 

 

 

싱글톤 패턴은 객체를 1번 생성하고 재사용할 수 있다는 장점이 있으므로 싱글톤 패턴이 필요한 경우도 분명히 있다. 하지만 싱글톤 패턴을 직접 구현하면 다른 단점들이 너무 크게 부각되기 때문에 활용이 쉽지 않다. 만약 프레임워크에게 싱글톤을 위임할 수 있다면 위와 같은 단점들을 많이 해결받을 수 있는데, 이러한 내용을 자세히 살펴보도록 하자.

 

 

 

 

2. 자바 싱글톤과 스프링 싱글톤의 차이


[ 자바 싱글톤과 스프링 싱글톤의 차이 ]

Spring과 같은 프레임워크를 통해 만들어지는 싱글톤은 자바를 통해 직접 구현하는 싱글톤과 다르다. 스프링 프레임워크를 통해 직접 객체(빈)들을 싱글톤으로 관리함으로써 자바 클래스에 불필요한 코드들을 제거하여 객체를 재사용함과 동시에 객체지향스러운 개발을 할 수 있도록 해주었다.

아까 보았던 클래스를 스프링 프레임워크를 통해 싱글톤으로 만들기 위해서는 다음과 같이 구현할 수 있다.

public class Person {

}

 

 

물론 위와 같은 코드에 경우에 따라 빈을 등록하기 위한 어노테이션 등이 추가될수는 있다. 하지만 이는 어떠한 단점을 유발하지 않는다.

대신 객체의 생성을 스프링에게 위임함으로써 위에서 봤던 예시와 다르게 싱글톤 패턴을 자바 언어 레벨에서 직접 구현하기 위한 내용들이 모두 제거되어서 위에서 설명한 모든 단점들을 극복한 것을 확인할 수 있다.

  • private 생성자가 필요 없어 상속이 가능하다.
  • 테스트하기 편리하다.
  • 프레임워크를 통해 1개의 객체 생성을 보장받을 수 있다.
  • 객체지향적으로 개발할 수 있다.

 

스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공하는데, 그것이 바로 싱글톤 레지스트리(Singleton Registry) 이다. 스프링 컨테이너는 싱글톤을 생성하고, 관리하고 공급하는 컨테이너이기도 하다. 싱글톤 레지스트리를 통해 static 메소드나 private 생성자 등을 사용하지 않아 객체지향적 개발을 할 수 있으며 테스트를 하기도 편리해진다.

 

 

 

 

 

 

기본적으로 싱글톤이 멀티쓰레드 환경에서 서비스 형태의 객체로 사용되기 위해서는 내부에 상태정보를 갖지 않는 무상태(Stateless) 방식으로 만들어져야 한다. 만약 여러 쓰레드들이 동시에 상태를 접근하여 수정한다면 상당히 위험하기 때문이다.

직접 싱글톤을 구현한다면 상당히 많은 단점들이 있겠지만, Spring 프레임워크에서 직접 싱글톤으로 객체를 관리해주므로, 우리는 더욱 객체지향적인 개발을 할 수 있게 된 것이다.

 

 

 

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG more
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함