본문 바로가기

Study Output for Myself/Javascript

[JS] 싱글톤(singleton) 패턴

싱글톤 위스키..ㅎㅎㅎ

클래스 / 생성자 함수

이름과 나이를 가진 사람이란 객체가 있다. 

printGreeting 메소드를 호출하면 이름과 나이를 넣어 인사를 한다.

 

"사람을 여러명 만들고 싶다." 고 하자.

이름과 나이를 넣으면 새로운 사람 객체를 만들어주는 클래스 혹은 생성자 함수를 생성하면 된다. 

//Person.js
class Person {
	constructure(name, age){
    	this.name = name;
        this.age = age;
    }
    
    printGreeting(){
    	console.log(`Hi, I'm ${this.name}. ${this.age} years old.`);
    }
 }
 
 export default Person;

인스턴스

클래스로 만든 새로운 객체를 '인스턴스'라고 한다.

아래 헤더 인스턴스와 애슐리 인스턴스를 만들었다.

//index.js
import Person from '../Person'

const Heather = new Person('Heather', 26);
const Ashley = new Person('Ashley', 21);

Heather.printGreeting() // "Hi, I'm Heather. 26 years old."

new 명령어를 통해 새로운 인스턴스를 만들면 아래와 같은 객체가 생선된 거다!

const Heather = {
	name : "Heather",
   	 age : 26,
    
    printGreeting:()=>{
		console.log(`Hi, I'm ${Heather.name}. ${Heather.age} years old.`)
   },
 }

 

싱글톤이란

생성자 함수의 특징은 인스턴스를 여러개를 만들 수 있다는 것이다. (아주 많이 만들 수 있다.)

위 예시처럼 다양한 이름의 다양한 나이의 사람이 여러명 필요한 경우가 대표적이다. 

 

그런데 싱글톤 패턴이란 클래스를 정의하고 하나의 인스턴스를 만들어서 그 하나의 인스턴스 자체만 내보내는 형식이다.

//Person.js
class Person {
	constructure(name, age){
    	this.name = name;
        this.age = age;
    }
    
    printGreeting(){
    	console.log(`Hi, I'm ${this.name}. ${this.age} years old.`);
    }
 }
 
 export default new Person('Heather', 26);

Person 클래스 대신 new Person('Heather', 26)이란 인스턴스를 내보냈다.

 

//index.js
import Heather from "../Person"

Heather.printGreeting() // "Hi, I'm Heather. 26 years old."

인스턴스를 import 해와서 printGreeting 메소드를 호출했다. 

 

결과적으로

1️⃣ index.js 파일에서 new 생성자를 쓰지 않는 다는 것과

2️⃣새로운 이름과 나이를 가진 인스턴스를 만들 수 없다는 차이점이 있다. 

 

이런 방식을 '싱글톤(Singleton) 패턴' 이라고 한다.

싱글톤 왜 쓰는 거야?

"클래스를 선언하는 이유가 인스턴스를 여러개 만들기 위한 게 아니었나?" 라는 생각이 들어서 처음에 싱글톤 패턴을 접했을 때 의아했다.

 

하나의 인스턴스만 사용할거면 객체로 선언하고 가져다가 쓰면 되는 거 아닌가? 

 

좀 더 공부해보니 객체 하나를 (내보내서) 사용하는 것도 싱글톤 패턴이라고 여겨진다.

 

다만 클래스는 객체가 가질 수 없는 private(자바스크립트에서는 필드, 메소드 앞에 #을 붙여주면 된다.) 생성자를 사용할 수 있다. 값을 은닉할 수 있음! 객체도 클로저를 사용해 프로퍼티와 메소드를 은닉하는 게 가능하지만 구현이 꽤 복잡하다. 

 

또 클래스는 constructure가 있어서 인스턴스를 생성하는 동시에 실행해야하는 코드가 있다면 유용하다. 

 

프로젝트 내에서 하나의 인스턴스만을 사용할 때 클래스를 선언하고 하나의 인스턴스만를 내보내는 싱글톤패턴을 사용하는 것으로 보인다. 

 

아래는 내가 작은 프로그램에 사용했던 클래스인데 이 클래스는 프로그램에서 딱 한번 인스턴스로 만들어진다.

그래서 class 대신 인스턴스를 생성해서 인스턴스 자체를 내보냈다.

 

코드 자체를 이해하려고 하지 말고 마지막 줄 코드만 보면 된다.

import { QuerySelector } from '../constants/Dom';
import { $ } from '../utils/DomUtils';

class MoneyInput {
  constructor() {
    this.#moneyInputEl = $(QuerySelector.MONEY_INPUT); //private field가 되어서 외부에서 값을 가져갈 수 없다
    this.#purchaseBtn = $(QuerySelector.PURCHASE_BUTTON);
  }

  activate(purchaseLottos) {
    this.#purchaseBtn.addEventListener('click', (e) => {
      e.preventDefault();
      const money = this.#moneyInputEl.value;
      this.#purchaseBtn.setAttribute('disabled', '');
      purchaseLottos(money);
    });
  }

  reset() {
    this.#moneyInputEl.value = '';
    this.#purchaseBtn.removeAttribute('disabled');
    this.#moneyInputEl.focus();
  }
}

export default new MoneyInput();

싱글톤 장점 & 단점

싱글톤 패턴의 장점은 메모리 상 인스턴스가 단 하나라는 점이다. 실수로 여러개의 인스턴스를 생성할 일이 없다. 

여러 파일에서 인스턴스를 가져가다가 쓸 때 인스턴스의 데이터를 공유한다는 점도 장점이다.

 

개인적으로는 코드가 한 줄 주는 것도 나름 장점이라 생각한다!

 

단점은 여러 파일에서 데이터를 공유하기 때문에 데이터를 변환할 때  인스턴스를 사용하고 있는 다른 파일에 의도치 않은 영향을 줄 수 있다는 점을 주의해야 한다. 

'Study Output for Myself > Javascript' 카테고리의 다른 글

[JS]proxy pattern  (0) 2023.03.14
[JS]insertAdjacentHTML  (0) 2022.08.24
[JS]History API  (0) 2022.08.23
[JS]fileReader(web-API)  (0) 2022.07.22
[JS]createDocumentFragment  (0) 2022.07.14