[디자인 패턴] 싱글톤 패턴

k·2024년 2월 11일
0

디자인 패턴

목록 보기
1/4

싱글톤 패턴

싱글톤 패턴이 뭐야?

싱글톤 패턴은 하나의 클래스에 오직 하나의 인스턴스만들 가지게하는 패턴이다.

위의 내용을 보고 사람들이 정적 클래스(Static class) 나 정적 메소드(Static Method)와 비슷한거 같은데 뭐가 말만 다른거 아니냐고 생각 할 수 있다. 일단 싱글톤 패턴과 정적 클래스의 가장 큰 차이점은 싱글톤은 인스턴스를 하나만 생성하는 것을 목표로 한다. 그런데, 정적 클래스는 인스턴스를 생성하지않는다.

또한 싱글톤에서는 정적 메소드가 분명 들어가지만, 이는 인스턴스를 관리하는 부분만 정적으로 관리가 된다. 나머지는 일반 인스턴스 메소드(Instance Method) 로 기능이 구현되게 된다.

싱글톤 패턴과 정적 클래스는 전혀 다른 존재이다.

싱글톤 패턴은 인스턴스 관리를 위해 정적 메소드를 사용한다.

이 관계에 대해서 잘 이해하고 있어야지 좋은 싱글톤 패턴을 프로젝트에 적용할 수 있다.

사용사례

DB 연결 동작 만들 때 주로 사용된다.

왜 그렇게 만드는거야?

보통 일반적으로는 하나의 클래스에 여러개의 개별 인스턴스를 생성할 수 있지만, 데이터베이스 연결 모듈과 같은 것을 직접 구현할 때는 동일 인스턴스를 사용하는 것이 훨씬 효율적이기 때문에 이런식으로 구성한다.

어떻게 만들어?

크게 자바스크립트와 자바로 그 예시를 들어보겠다.

JAVASCRIPT

//싱글톤을 적용하지 않은 예시
class Singleton{
	constructor(){}
}

const a = new Singleton();
const b = new Singleton();
console.log(a==b);
//false


//싱글톤을 적용한 예시
class Singleton{
 	constructor(){
    	if(!Singleton.instance){
        	Singleton.instance = this;
        }
      return Singleton.instance;
    }
}

const a = new Singleton();
const b = new Singleton();
console.log(a==b);
//true

생성자 return에 대해서 궁금해할 수도 있어서 먼저 설명하겠다.
자바스크립트는 생성자가 묵시적으로 this를 return 한다.
this는 현재 인스턴스라 생각하면 된다. 이를 return 해 줌으로써, 인스턴스 생성이 되는 것이다.

하지만, 위에서는 return Singleton.instance를 return 해줬다. 즉 생성된 인스턴스가 있으면, 그 인스턴스를 return 해주는 것이다.

JAVA

//싱글톤 사용하지않은 예시
class Singleton{
	public Singleton(){}
}

public class Main{
	public static void main(String[] args){
    	Singleton a = new Singleton();
       Singleton b = new Singleton();
       if(a!=b){
       		System.out.println(false);
       }
    }
}
//싱글톤 사용한 예시
class Singleton{
	private static class singletonInstanceHoldeer{
    	private static final Singleton singleton = new Singleton();
    }
    public static Singleton getInstance(){
    	return singleInstanceHolder.singleton;
    }
}

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

여기서 보게되면, 자바에서의 싱글톤 패턴은 간단하게 아래 2가지로 나누어진다.

  • 인스턴스는 정적 메소드나 클래스로 관리 (저장 및 return)

    이 때, return 시에 만들어둔 인스턴스를 반환

  • 나머지는 인스턴스 메소드로써 기능 구현

    생성된 인스턴스가 이를 사용할 수 있게 하기 위함.

그럼 싱글톤이 무조건 좋은거야?

일단 결론부터 말하면 아니다.

싱글톤은 큰 단점이 존재한다.
주로 TDD를 할 때는 유닛 테스트로 하는데, 이 때 테스트가 서로 독립적이여야한다.

하지만, 싱글톤 패턴은 하나의 인스턴스만을 사용하기에 각 테스트마다 독립적인 인스턴스를 만들기 어렵다. 또한, 모듈 간의 강한 결합이 생길 수 있다.

이는 의존성 주입(DI)를 통해 느슨한 결합을 만들어서 극복할 수 있다.

그럼 전부 의존성 주입하면 되는건가?

의존성 주입을 하게되면 물론 추상화 레이어(Abstract Layer)가 중간에 들어가는 구조 상 모듈들을 쉽게 교체할 수 있어서 테스트 및 마이그레이션에 용이하다. 또한 구현 시 추상화 레이어(Abstract Layer)를 넣고, 이를 기반해 구현체를 넣어주기 때문에 의존성의 플로우가 일관되고, 모듈 간의 관계가 조금 더 명확해진다.

그럼에도 불구하고 의존성 주입은 필연적으로 모듈들이 분리되기 때문에, 클래스 수가 늘어난다.

결론적으로는 복잡성이 증가할 수 있다.

이로 인해서 런타임 패널티가 생기기도 한다.

런타임 패널티란?

프로그램이 실행 중에 발생하는 성능 저하나 부하를 나타내는 말이다.

결론적으로 필요에 따른 싱글톤 패턴은 리소스의 낭비를 막을 수 있기 때문에 매우 추천된다. 하지만 사용을 위해서는 의존성 주입 원칙을 지켜서 만들게 되면 보다 효율적인 싱글톤 패턴을 만들 수 있다.

공부하면서 적은 내용이기 때문에 잘못되게나 틀린 부분은 댓글로 명시해주시면 수정하겠습니다. :)

profile
You must do the things you think you cannot do

0개의 댓글