CS/디자인 패턴과 프로그래밍 패러다임

싱글톤 패턴(Singleton Pattern)

calendar2 2024. 6. 21. 01:14

싱글톤이란?

하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴

 

하나의 클래스를 기반으로 여러 개의 개별적인 인스턴스를 만들 수 있지만, 그렇게 하지 않고 하나의 클래스를 기반으로 단 하나의 인스턴스를 만드는 패턴이다. 일반적으로 데이터베이스 연결 모듈에서 많이 사용된다.

예제 코드

일반적으로 싱글톤 패턴은 자바에서 사용빈도가 높으므로 자바로 예시를 들겠다.

class Singleton {
    private static class singleInstanceHolder {
        private static final Singleton INSTANCE = new Singleton();
    }
    
    public static Singleton getInstance() {
        return singleInstanceHolder.INSTANCE;
    }
}

public class HelloWorld {
    public static void main(String[] args) {
        Singleton a = Singleton.getInstance();
        Singleton b = Singleton.getInstance();
        
        System.out.println(a.hashCode());
        System.out.println(b.hashCode());
        
        if (a == b) {
            System.out.println(true);
        }
    }
}

/*
출력 결과
705927765
705927765
true
*/

 

위 코드를 하나씩 해석해보자.

  1. Singleton 클래스에 singleInstanceHolder 클래스를 사용하여 인스턴스를 생성한다.
  2. singleInstanceHolder 클래스는 private으로 선언하여 외부에서 인스턴스를 생성할 수 없다.
  3. Singleton 클래스에 getInstance() 메서드를 사용하여 singleInstanceHolder.INSTANCE 라는 인스턴스를 제공받을 수 있다.
  4. main 메서드에서 변수 a와 b에 싱글톤 인스턴스를 할당했다.
  5. hashCode() 메서드를 사용하여 a와 b가 동일한 인스턴스를 할당받았는지 확인해보았으며, a == b 비교를 통해서도 동일한 인스턴스임을 확인하였다.

이처럼 싱글톤 패턴은 하나의 클래스에 하나의 인스턴스만을 생성하여 다른 모듈들에서 같은 인스턴스를 공유하며 사용이 가능하다.

싱글톤 패턴의 장단점

장단점이 꽤 명확한 패턴이다.

장점

  • 인스턴스를 생성할 때 들어가는 비용이 줄어든다
  • 애플리케이션에서 유일한 인스턴스임이 보장된다

단점

  • 높은 결합도를 가진다
  • 프로젝트에서 각 테스트별로 독립적인 인스턴스를 만들기 어렵다
  • TDD 개발 방식을 진행할 때 걸림돌이 된다

현재 많은 각광을 받는 TDD 개발 방식에 어려운 패턴이라는 것은 상당히 큰 단점이라고 생각이 든다. 따라서, 하나의 모듈 또는 모듈 내부에 어떠한 객체를 정의할 때와 같이 굉장히 지엽적인 상황에서 사용함이 좋아보인다.

 

싱글톤 패턴이 가진 높은 결합도를 더 느슨하게 만드는 방법이 있다.

의존성 주입(Dependency Injection)

DI라고 불리는 의존성 주입 방식을 사용하는 것이 결합도를 낮추는 방법이다.

싱글톤 패턴은 전역에서의 접근을 허용하기 때문에 다른 클래스와 직접적으로 의존하는 경우가 발생할 수 있다.

위에 예제 코드를 다시 살펴보자. Singleton 클래스가 main 메서드에 직접적으로 호출되어 의존관계를 갖고있다.

이를 main 메서드가 아닌 다른 클래스의 다른 메서드에서 호출했다면 두 객체 간에 의존 관계가 만들어진 것이다.

 

때문에 두 객체가 서로 직접적으로 호출하지 않고 interface와 같은 클래스를 이용해 가로채어 결합도를 낮춘다.

DI에 대한 더욱 자세한 내용은 다음 링크를 참고하기 바랍니다.

[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유

 

[Spring] 의존성 주입(Dependency Injection, DI)이란? 및 Spring이 의존성 주입을 지원하는 이유

1. 의존성 주입(Dependency Injection)의 개념과 필요성 [ 의존성 주입(Dependency Injection) 이란? ] Spring 프레임워크는 3가지 핵심 프로그래밍 모델을 지원하고 있는데, 그 중 하나가 의존성 주입(Dependency Inj

mangkyu.tistory.com

장점

  • 모듈들을 쉽게 교체할 수 있는 구조
    • 테스팅이 간편해진다
    • 마이그레이션이 수월하다
  • 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주는 방식
    • 애플리케이션 의존성 방향이 일관된다
    • 애플리케이션을 쉽게 추론할 수 있다
    • 모듈 간의 관계들이 더 명확해진다

단점

  • 모듈들의 더 많은 분리
    • 복잡성이 높아진다
    • 런타임 페널티가 증가한다

의존성 주입 원칙

의존성 주입 방식에는 몇 가지 원칙이 존재한다.

  1. 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 한다
  2. 상위 모듈, 하위 모듈 둘 다 추상화에 의존해야 한다
  3. 단, 추상화는 세부 사항에 의존하면 안된다

참고자료

'CS > 디자인 패턴과 프로그래밍 패러다임' 카테고리의 다른 글

SOLID 원칙 - 의존 역전 원칙  (0) 2024.12.30
SOLID 원칙 - 개방 폐쇄 원칙  (2) 2024.12.17
객체지향 프로그래밍  (0) 2024.06.24
프로그래밍 패러다임  (0) 2024.06.24
디자인 패턴  (0) 2024.06.19