CodeLyst

[React Design Pattern] Singleton Pattern

#React@kkiyya
thumb nail

Sigleton Pattern이란?

객체의 인스턴스가 1개만 생성되는 패턴을 의미한다.

프로그램 내에서 공유를 해야하는 자원이 있을 때, 객체 하나만을 생성하여 해당 객체에 접근하여 공유자원을 사용합니다.



Singleton Pattern의 장점

1. 메모리 공간 절약

하나의 인스턴스로만 생성하고 접근하면, 메모리 낭비를 줄일 수 있습니다.

2. 전역적으로 접근 가능

전역 변수로서 사용되며, 전역 범위에서 사용할 수 있습니다.


Singleton Pattern의 단점

1. 의존도 상승

한 어플리케이션 내에 전역변수를 놓고 어디서든 접근하는 방식은 좋지 않습니다. 어디서는 수정되고, 어디서는 접근할 수 있기 때문에, 데이터간 충돌이 날 수 있습니다. (코드 실행순서에 따라서도 생각외의 일이 일어날 수 있습니다.) 따라서, Sigleton 내부에 기능이 들어가있는 것을 피해야합니다.


객체 리터럴

객체는 아래와 같이 생성할 수 있습니다. 이 것도 마찬가지로 싱글톤의 한 예제이기도 합니다. 저 object 객체는 유일한 값이기 때문입니다.

var object = { name: "kkiyya", hello: function () { console.log("hello", this.name); }, }; object.hello();

하지만, 이 객체의 내용은 공개되어 있습니다. 이걸 비공개 형식으로 만들어주는 것이 싱글톤입니다.


싱글톤 패턴 예시

이걸 한 번 클래스 형태로 바꿔보겠습니다.

export default class Singleton { constructor() { this.name = ""; } setName(name) { this.name = name; console.log("set name", name); } hello() { console.log("hello", this.name); } }

이렇게 만든 클래스는 아래와 같이 여러번의 인스턴스화를 시킬 수 있습니다.

const kki = new Singleton(); const yya = new Singleton();

싱글톤은 인스턴스화가 한 번만 가능합니다! 그 역할을 할 수 있도록 구현해보면 아래와 같습니다.

class Singleton { constructor() { if (Singleton.instance) { throw new Error("Multiple!"); } this.name = "init"; Singleton.instance = this; } setName(name) { this.name = name; console.log("set name", name); } hello() { console.log("hello", this.name); } } const kki = new Singleton(); const yya = new Singleton();

1. 이미 해당 class 인스턴스가 있는지 없는지 체크합니다.

if (Singleton.instance) { throw new Error("Multiple!"); }

2. 만약 없으면, init이라는 값으로 현재 만들어지는 인스턴스의 프로퍼티 값을 할당해줍니다.

this.name = "init"; Singleton.instance = this;

Error객체를 "Multiple"이라고 메세지를 입력해주었기 때문에 해당 코드를 생성하면

아래 2개 인스턴스화 시키는 코드때문에 해당오류가 나는 것을 확인할 수 있습니다.


React Singleton 패턴 적용

Singleton의 행동이 어찌 전역상태를 관리하는 redux와 비슷해보일 수 있는데, Singleton과 같이 값을 변경시킬 수 있는 mutable state인 반면에 Redux는 순수함수 reducer로만 값의 상태를 바꿀 수 있는 read-only state를 제공합니다.


ES10 Private

ES10부터 private사용이 가능해졌습니다! 아래 코드처럼 #을 사용해서 private이라고 알려줍니다.

class Singleton { #name = ""; #setName(name) { this.#name = name; console.log("set name", name); } hello() { console.log("hello", this.name); } }

Reference

https://www.zerocho.com/category/JavaScript/post/57541bef7dfff917002c4e86

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields