스터디
[JavaScript] 싱글톤 패턴과 정적 클래스 본문
< 싱글톤 패턴 >
> 싱글톤(Singleton) 패턴이란 객체의 인스턴스가 오직 1개만 생성되는 패턴을 의미한다.
보통 객체를 만들 때 하나의 생성자로 여러 개의 서로 다른 객체를 만들 수 있는데, 싱글톤에서는 단 하나의 객체만 존재하는 것이 보장된다.
가장 간단한 싱글톤 예제는 아래와 같이 객체 리터럴을 이용하는 것이다.
const plus = { a: 1, b: 2 };
const minus = { a: 1, b: 2 };
동일한 키와 값을 똑같이 지정했더라도 참조하는 주소값이 다르기 때문에 plus와 minus는 각각 유일하게 존재하는 서로 다른 객체이다.
그렇지만 이렇게 객체 리터럴로 사용하지 않고 비공개된 프로퍼티나 함수를 정의하고 싶다면 클로저(closure)를 사용해야 한다. 아래처럼 IIFE(즉시 실행 함수)로 비공개 변수를 가질 수 있게 만들어주면 된다.
const SingletonClass = function() {
let instance;
function init() { // 싱글톤 객체를 리턴할 비공개 함수
return {
publictMethod: function() {
return 'public method';
},
publicProp: 'public variable',
};
}
return {
getInstance: function() {
if (instance) {
return instance; // 있으면 그냥 반환
}
instance = init();
return instance; // 없으면 객체 생성 후 반환
}
};
})();
const a = SingletonClass.getInstance();
console.log(a.publicProp, 'a'); // 'public variable'
const b = SingletonClass.getInstance();
console.log(a === b) // true
비공개 함수 init()의 return문에서 객체 리터럴로 정의되는 인스턴스가 싱글톤 객체이다.
SingletonClass 내부에 있는 getInstance 메소드는 생성된 인스턴스가 있으면 이미 생성된 객체를 리턴하고, 아니라면 객체를 생성해서 리턴한다.
즉, 객체를 여러 번 생성하더라도 각자 다른 객체가 아니라 한 개의 동일한 객체를 가리키게 되는 것이다.
싱글톤 패턴에서는 이미 객체가 생성되었는지 여부를 판단하는 instance와 같은 내부 변수가 필요하다.
클로저를 통해 getInstance 메소드가 호출되는 시점에 instance의 값에 접근할 수 있고, getInstance의 호출이 끝나더라도 변경된 instance의 값은 유지된다.
> 장점
- 객체를 생성할 때마다 메모리 영역을 할당받아야 하는데, 싱글톤 패턴을 사용하면 메모리 낭비를 방지할 수 있다.
- 싱글톤으로 구현한 인스턴스는 '전역'이므로, 다른 클래스의 인스턴스들이 데이터를 공유하는 것이 가능한 장점이 있다.
> 단점
- 객체지향 설계 원칙 중에 개방 폐쇄 원칙(OCP)이 존재하는데, 만약 싱글톤 인스턴스가 혼자서 너무 많은 일을 하거나 많은 데이터를 공유시키면 다른 클래스들 간의 결합도가 높아져 OCP 원칙이 위배된다.
- 결합도가 높아지게 되면, 유지보수가 힘들고 테스트도 원활하게 진행할 수 없는 문제점이 발생한다.
- 또한 멀티 스레드 환경에서 동기화 처리를 하지 않았을 때, 인스턴스가 2개가 생성되는 문제도 발생할 수 있다.
- 따라서 반드시 싱글톤이 필요한 상황이 아니면 지양하는 것이 좋다고 한다. (설계 자체에서 싱글톤 활용을 원활하게 할 자신이 있으면 괜찮다.)
< Static Class (정적 클래스) >
> 모든 메소드가 static인 클래스를 지칭한다.
inner static class를 뜻하기도 한다.
> 정적 클래스를 사용하는 이유
- 상태를 가지고 있지 않고 global access를 제공할 때 유용하다.
- static은 컴파일할 때 static binding으로 싱글톤보다 조금 더 빠르다.
- 클래스 자체에 static을 붙여 사용할 수 없다. (inner class일 때만 가능하다.)
> Static Variable
- 메모리에 고정적으로 할당되어 프로그램이 종료될 때까지 해제되는 변수이다.
> Static Method
- 객체 생성 없이 메소드를 바로 호출할 수 있다.
- 객체 생성 없이 접근하는 메소드이므로 static이 아닌 변수는 사용이 불가능하다.
> Static Class
- Static Nested Class
- 외부 클래스 자원 중 static이 붙은 것만 사용할 수 있다.
< 싱글톤과 정적 클래스의 차이 >
- 싱글톤은 인스턴스를 가지지만 정적 클래스는 인스턴스를 가지지 않는다.
(싱글톤 OOP 지향 O, 정적 클래스 OOP 지향 X) - 싱글톤은 인터페이스 구현이 가능하지만 정적 클래스는 불가능하다.
- 싱글톤은 상속이 되지만, 정적 클래스는 불가능하다.
- 싱글톤은 필요에 따라 Lazy 가능, 정적 클래스는 Static Binding으로 빠르게 로딩
> 싱글톤은 OOP일까?
- 싱글톤이 상태를 가지는 객체일 경우 전역으로 접근하는 여러 다른 스레드에서 상태를 바꾸게 되는 위험성이 존재한다.
- 생성자에서 의존성이 드러나지 않는다.
-> 상태가 없는 객체나 설계 상 유일해야 하는 시스템 컴포넌트를 싱글톤으로 구현한다.
'백엔드' 카테고리의 다른 글
CORS (0) | 2023.04.13 |
---|---|
[JavaScript] 프로토타입과 클래스 (3) | 2023.04.10 |
MVC 패턴 (2) | 2023.04.07 |
[JavaScript] 동기? 비동기? (0) | 2023.04.06 |
[JavaScript] async/await (0) | 2023.04.06 |