싱글톤 패턴 Singleton pattern

석준·2022년 8월 22일
0

Computer Science

목록 보기
1/6
post-thumbnail

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

싱글 톤 패턴

하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴으로 보통 DB 연결 모듈에 많이 사용.
하나의 인스턴스를 만들어 놓고 해당 인스턴스를 다른 모듈들이 공유하며 사용하기 때문에, 인스턴스를 생성할 때 드는 비용이 줄어드는 장점이 있으나 의존성이 높아진다는 단점이 있다.

1) JS의 싱글톤 패턴

JS 리터럴{} 또는 new Object로 객체를 생성하게 되면 다른 어떤 객체와도 같지 않기 때문에 이 자체만으로 싱글톤 패턴을 구현할 수 있다.

const obj = {
  a: 5
}

const obj2 = {
  a: 5
}
console.log(obj == obj2)
// false
class Mytone {
  constructor(){
    if (!Mytone.istance){
      Mytone.instance = this
    }
    return Mytone.instance
  }
  getInstance() {
    return this.instance
  }
}
const a = new Mytone()
const b = new Mytone()
console.log(a == b)
// true

2) mongoDB 싱글톤 패턴

Node.js에서 mongoDB 데이터베이스를 연결할 때 쓰는 mongoose 모듈에서 connect() 함수는 싱글톤 인스턴스를 반환한다.

import Mongoose

Mongoose.prototype.connect = function(uri, option, callback){
  const = _mongoose = this instanceof Mongoose ? this : mongoose;
  const conn = _mongoose.connection;
  
  return _mongoose._promiseOrCallback(callback, cb => {
    conn.openUri(uri, options, err => {
      if (err != null) {
        return cb(err);
      }
      return cb(null, _mongoose);
    });
  });
});

3) MySQL 싱글톤 패턴

Node.js에서 MySQL DB연결할 때도 싱글톤 패턴이 쓰임
메인 모듈에서 DB연결에 관한 인스턴스를 정의하고 다른 모듈에서 해당 인스턴스를 기반으로 쿼리를 보내는 형식에서 쓰인다.

// 메인 모듈
const mysql = require('mysql');
const pool = mysql.createPool({
  connectionLimit: 10,
  host: 'example.org',
  user: 'seokjun',
  password: 'secret',
  database: 'seokjunDB',
});

pool.connect();

// 모듈 A
pool.query(query, function(error, results, fields){
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

// 모듈 B
pool.query(query, function(error, results, fields){
  if (error) throw error;
  console.log('The solution is: ', results[0].solution);
});

싱글톤 패턴의 단점

  1. TDD(Test Driven Development)할 때 주로 단위 테스트를 하는데, 테스트가 서로 독립적이어야 하며 어떤 순서로든 실행해야 하지만, 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 각 테스트 마다 '독립적인' 인스턴스를 만들기 어렵다.
  2. 사용하기 쉽고 굉장히 실용적이지만, 모듈간의 결합을 강하게 만들 수 있다. 따라서 의존성 주입(DI, Dependency injection)을 통해 모듈 간의 결합을 조금 더 느슨하게 만들어 해결할 수 있다.

✅의존성 주입(DI, Dependency injection)

의존성: 종속성이라고도 하며 A가 B에 의존성이 있다는 것은 B의 변경사항에 대해 A 또한 변해야 된다는 것을 의미한다.

메인 모듈이 직접 하위 모듈에 대한 의존성을 주기 보다는 중간에 의존성 주입자(dependency injector)가 이 부분을 가로채 메인 모듈이 '간접'적으로 의존성을 주입하는 방식.
이를 통해 메인 모듈(상위 모듈)은 하위 모듈에 대한 의존성이 떨어지게 됩니다. 이를 '디커플링 된다' 라고도 한다.

📌의존성 주입의 장점
모듈들을 쉽게 교체할 수 있는 구조가 되어 테스팅과 마이그레이션 수월
구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 넣어 주기 때문에 앱의 의존성 방향이 일관됨
앱의 추론이 쉬워 모듈들 관계가 명확해진다

📌의존성 주입의 단점
모듈들의 분리로 수가 늘어나 복잡성이 증가될 수 있어 런타임이 길어질 수 있다

📌의존성 주입 원칙
상위 모듈은 하위 모듈의 어떠한 것도 가져오지 않아야 한다.
둘 다 추상화에 의존해야 하며, 이때 추상화는 세부 사항에 의존하지 말아야 한다.

profile
파이썬 서버 개발자 지망생

0개의 댓글