Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
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
Tags
more
Archives
Today
Total
관리 메뉴

엘라의 개발 스케치 Note

[CS 전공지식 노트] 1.1.1 싱글톤 패턴 본문

CS/면접을 위한 CS 전공지식 노트

[CS 전공지식 노트] 1.1.1 싱글톤 패턴

엘라랑이 2024. 3. 4. 18:59

# 싱글톤 패턴

더보기

? 싱글톤 패턴

- 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴 -> 해당 인스턴스를 다른 모듈들이 공유하며 사용
- 보통 데이터베이스 연결 모듈에 많이 사용

 

 

! 장단점

  • 장점
    • 인스턴스를 생성할 때 드는 비용이 줄어듬
  • 단점
    • 의존성이 높아짐

 

! 자바스크립트의 싱글톤 패턴

더보기
  • 자바스크립트에서는 리터럴 {} 또는 new Object로 객체를 생성하게 되면 다른 어떤 객체와도 같지 않기 때문에 이 자체만으로 싱글톤 패턴 구현 가능 
    • obj와 obj2는 다른 인스턴스를 가짐
const obj = {
    a: 27
}
const obj2 = {
    a: 27
}
console.log(obj === obj2)
// false

 

  • 실제 싱글톤 패턴 코드
    • Singleton.instance라는 하나의 인스턴스를 가지는 Singleton 클래스를 구현한 모습
    • 이를 통해 a와 b는 하나의 인스턴스를 가짐
class Singleton {
    constructor() {
        if (!Singleton.instance) {
            Singleton.instance = this
        }
        return Singleton.instance
    }
    getInstance() {
        return this 
    }
}
const a = new Singleton()
const b = new Singleton() 
console.log(a === b) // true

 

! 데이터베이스 연결 모듈

더보기
  • 싱글톤 패턴에서 많이 사용됨
  • DB.instance라는 하나의 인스턴스 기반 -> a, b를 생성
  • DB 연결에 관한 인스턴스 생성 비용 절약
// DB 연결을 하는 것이기 때문에 비용이 더 높은 작업 
const URL = 'mongodb://localhost:27017/kundolapp' 
const createConnection = url => ({"url" : url})    
class DB {
    constructor(url) {
        if (!DB.instance) { 
            DB.instance = createConnection(url)
        }
        return DB.instance
    }
    connect() {
        return this.instance
    }
}
const a = new DB(URL)
const b = new DB(URL) 
console.log(a === b) // true

 

! 자바에서의 싱글톤 패턴

더보기

 

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. 클래스안에 클래스(Holder), static이며 중첩된 클래스인 singleInstanceHolder를 
기반으로 객체를 선언했기 때문에 한 번만 로드되므로 싱글톤 클래스의 인스턴스는 애플리케이션 당 하나만 존재하며 
클래스가 두 번 로드되지 않기 때문에 두 스레드가 동일한 JVM에서 2개의 인스턴스를 생성할 수 없습니다. 
그렇기 때문에 동기화, 즉 synchronized를 신경쓰지 않아도 됩니다. 
2. final 키워드를 통해서 read only 즉, 다시 값이 할당되지 않도록 했습니다.
3. 중첩클래스 Holder로 만들었기 때문에 싱글톤 클래스가 로드될 때 클래스가 메모리에 로드되지 않고 
어떠한 모듈에서 getInstance()메서드가 호출할 때 싱글톤 객체를 최초로 생성 및 리턴하게 됩니다. 
*/

 

! mongoose의 싱글톤 패턴

더보기
  • Node.js에서 MongoDB 데이터베이스를 연결할 때 쓰는 mongoose 모듈에서 볼 수 있음
  • mongoose의 DB 연결하는 connect() 함수 -> 싱글톤 인스턴스 반환
Mongoose.prototype.connect = function(uri, options, callback) {
	const_mongoose = this instanceof Mongoose ? this : mongoose;
    const conn = _mongoose.connection;
    
    return _mongoose._promise0rCallback(callback, cb => {
    	conn.openUri(uri, options, err => {
        	if (err != null) {
            	return cb(err);
            }
            return cb(null, _mongoose);
        });
    });
};

 

! MySQL의 싱글톤 패턴

더보기
  • Node.js에서 MySQL DB 연결 시 싱글톤 패턴 사용
  • 메인 모듈에서 DB 연결에 관한 인스턴스 정의 -> 다른 모듈에서 해당 인스턴스를 기반으로 쿼리를 보내는 형식
// 메인 모듈
const mysql = require('mysql');
const pool = mysql.createPool({
	connectionLimit: 10,
    host: 'example.org',
    user: 'kundol',
    password: 'secret',
    database: '승철이디비'
});
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);
});

 

! 싱글톤 패턴의 단점

더보기
  • TDD(Test Driven Development)에서 방해가 됨
    • TDD -> 단위 테스트 주로
      • 단위 테스트: 테스트가 서로 독립적, 테스트를 어떤 순서로든 실행할 수 있어야 함
    • But, 싱글톤 패턴은 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴
      • -> 각 테스트마다 '독립적인' 인스턴스를 만들기 어려움

 

! 의존성 주입

더보기
  • 싱글톤 패턴은 사용하기 쉽고 굉장히 실용적
    • But, 모듈간의 결함을 강하게 만들 수 있다는 단점
    • -> 의존성 주입(DI, Dependency Injection)을 통해 모듈간 결합 느슨하게 만들어 해결 가능
      • 의존성=종속성: A가 B에 의존성이 있다=B의 변경 -> A도 변경 필요

 

  • 메인 모듈 직접 다른 하위 모듈에 대한 의존성 주입
  • -> 중간의 의존성 주입자가 메인 모듈에서 간접적으로 의존성 주입
    • 메인(상위) 모듈은 하위 모듈에 대한 의존성이 떨어지게 됨 = 디커플링이 된다

 

  • 장점
    • 모듈들을 쉽게 교체할 수 있는 구조가 됨
      • 테스팅 쉬움
      • 마이그레이션 수월
    • 구현할 때 추상화 레이어를 넣고 이를 기반으로 구현체를 주입
      • 애플리케이션 의존성 방향 일관
      • 애플리케이션 쉽게 추론
      • 모듈 간 관계 명확
  • 단점
    • 모듈들이 더욱 분리 -> 클래스 수가 늘어남
      • 복잡성 증가
      • 약간의 런타임 패널티
  • 원칙
    • 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 않아야 함
    • 둘 다 추상화의 의존해야 함
    • 추상화는 세부 사항에 의존하지 말아야 함
Comments