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

변진상·2024년 1월 16일
0

학습 기록

목록 보기
1/31
post-thumbnail

이 글은 면접을 위한 CS 전공지식노트의 책을 읽고 학습 후 스터디 공유를 위한 글입니다.

디자인 패턴이란?

디자인 패턴은 프로그램을 설계할 때 발생했던 문제점들을 객체 간 상호 관계 등을 이용해 해결할 수 있는 하나의 “규약” 형태로 만들어 놓은 것.

즉, 프로그램 설계시 발생한 문제를 해결하기 위한 객체의 관계, 구조적 규약


싱글톤 패턴(Singleton Pattern)

싱글톤 패턴이란?

싱글톤 패턴은 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴(새로 인스턴스를 생성하더라도 같은 인스턴스를 가리킵니다.)

구현 코드

class Singleton {

	constructor(){
		**if(!Singleton.instance) Singleton.instance = this;
		
		return Singleton.instance;**
	}

	getInstance(){
		return this.instance;
	}
}

두 인스턴스가 같은 인스턴스를 가리키는 것을 알 수 있다.

싱글톤 패턴을 주로 어디에 사용하는가?

데이터 베이스 연결 모듈

Mongoose의 싱글톤 패턴

실제 싱글톤 패턴은 Node.js에서 MongoDB 데이터베이스를 연결할 때 스는 mongoose 모듈에서 확인 가능.

mongoose의 데이터베이스를 연결할 때 쓰는 connect()라는 함수는 싱글톤 인스턴스를 반환한다.

// Mongoose의 프로토타입을 확장하여 connect 메서드를 수정합니다.
Mongoose.prototype.connect = function (uri, options, callback) {
  // 'this'가 Mongoose의 인스턴스를 가리키는지 확인하고, 아닐 경우 Mongoose 생성자를 사용합니다.
  **const _mongoose = this instanceof Mongoose ? this : Mongoose;**
  // Mongoose에서 커넥션 객체를 가져옵니다.
  const conn = _mongoose.connection;

  // 제공된 콜백 함수에 따라 프로미스 또는 콜백을 반환합니다.
  return _mongoose._promiseOrCallback(callback, cb => {
    // 지정된 URI와 옵션으로 연결을 시도합니다.
    conn.openUri(uri, options, err => { 
      // 연결 과정에서 오류가 발생하면 해당 오류를 콜백에 전달합니다.
      if (err != null) {
        return cb(err);
      }
      // 연결이 성공하면 오류를 'null'로 설정하고 Mongoose 객체를 반환합니다.
      return cb(null, _mongoose);
    })
  })
}

현재 인스턴스가 Mongoose의 인스턴스인지 확인하고, 그렇지 않은 경우 Mongoose 생성자를 사용하여 _mongoose 변수에 할당합니다. 이를 통해 코드는 항상 동일한 Mongoose 인스턴스를 사용하도록 보장한다.

싱글톤 패턴의 장점

  • 자원 관리: 단일 인스턴스를 유지하기 때문에 메모리 자원을 효율적으로 관리할 수 있습니다.
  • 전역적인 접근: 여러 부분에서 같은 인스턴스에 접근할 수 있어, 데이터 공유 및 변경이 용이합니다.
  • 인스턴스 제어: 한 번의 인스턴스 생성을 보장하므로 객체의 상태 및 동작을 전역적으로 조절할 수 있습니다.

싱글톤 패턴의 단점

  • 의존성 증가: 전역적으로 접근 가능한 단일 인스턴스는 의존성을 증가시킬 수 있습니다. → 이를 해결하는 방법으로 의존성 주입 패턴이 있다. 면접시 이 부분까지 언급이 된다면 좋을 것 같다.
    • 의존성 주입이란?: 메인 모듈에서 하위 모듈에서 직접 의존성을 주기 보다는 중간의 의존성 주입자가 이 부분을 가로채 메인 모듈이 간접적으로 의존성을 주입하는 방식이다. 이를 통해 상위 모듈은 하위모듈에 대해 의존성이 떨어지게 된다(디커플링 된다.).
    • 의존성 주입 장점
      • 모듈을 쉽게 교체가 가능해 테스팅, 마이그레이션 용이
      • 구현시 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에 의존성의 방향이 일관 → 관계가 명확해지고 쉽게 추론 가능
    • 의존성 주입 단점
      • 모듈이 분리되어 클래스 수가 늘어나 복잡성 증가 → 약간의 런타임 페널티가 생기기도 함
    • 의존성 주입 원칙
      • 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야한다.
      • 둘 다 추상화에 의존해야하며 추상화는 세부사항에 의존하지 말아야한다.
  • TDD(Test Driven Development)를 할 때 걸림돌이 된다.
    • TDD의 경우 단위테스트를 주로 한다.
    • 단위 테스트는 **테스트가 서로 독립적이어야 한다**. 그리고 **테스트를 어떤 순서로든 실행할 수 있어야한다**.
    • 싱글톤 패턴을 사용할 경우 각 테스트마다 독립적인 인스턴스를 만들기 어렵다. 즉, 모의(mock) 객체를 생성하는 데 어려움을 줄 수 있다.
  • 코드 복잡성: 다른 부분에서 동일한 인스턴스에 접근할 수 있으므로 코드의 복잡성이 증가할 수 있습니다.
  • 멀티 스레드 환경에서 여러 인스턴스가 생성되는 것을 방지하기 위한 동기화 처리를 해야하며 이는 많은 양의 코드를 작성을 요구함

더 공부해 보면 좋을 내용

  • IIFE 패턴과 클로저를 이용한 싱글톤 패턴 구현
  • JS 프로토타입을 이용한 클래스 구현
  • static을 이용한 구현체의 장,단점 비교…!
profile
자신을 개발하는 개발자!

0개의 댓글