노출 모듈 패턴의 경우 참조하는 함수를 수정할 수 없습니다. 비공개 함수가 비공개 구현을 참조하기 때문에 발생합니다. 비공개 구현 함수를 직접적으로 수정하지 않는 이상 함수를 수정할 수 없습니다.
7.5 싱글톤 패턴
클래스의 인스턴스가 오직 하나만 존재하도록 제한하는 패턴입니다. 이 패턴은 전역에서 접근 및 공유해야 하는 단 하나의 객체가 필요할 때 유용합니다.
싱글톤 패턴은 정적 클래스나 객체와는 다르게 초기화를 지연시킬 수 있습니다. 초기화 시점에 필요한 특정 정보가 유효하지 않을 수도 있기 때문입니다.
let instance;
const privateMethod = () => {
console.log("I am private");
}
class Singleton {
constructor(){
if(!instance) {
this.publicProperty = 'I am public';
instance = this;
}
return instance;
}
}
export default Singleton()
싱글톤과 정적 클래스 사이의 차이점을 명확히 아는 것은 중요합니다. 정적 인스턴스로 구현했다고 하더라도, 필요할 때까지는 리소스나 메모리를 소모하지 않도록 지연 생성할 수도 있습니다.
싱글톤은 유용한 패턴입니다. 다만 자바스크립트에서 싱글톤이 필요하다는 것은 설계를 다시 생각해 봐야 한다는 신호일 수도 있습니다. C++이나 자바와 달리 자바스크립트는 객체를 직접적으로 생성할 수 있습니다.
따라서 싱글톤 클래스를 만드는 대신에 직접 객체 하나를 생성할 수도 있습니다.
자바스크립트에서 싱글톤을 사용할 경우 다음과 같은 단점이 있습니다.
싱글톤임을 파악하는 것이 힘들다.
테스트하기 힘들다.
신중한 조정이 필요하다.
7.5.1 리액트의 상태관리
리액트를 통해 웹 개발을 한다면 싱글톤 대신 Context API나 리덕스 같은 전역 상태 관리 도구를 이용하여 개발할 수도 있습니다. 싱글톤과 달리, 이러한 전역 상태 관리 도구는 변경 불가능한 읽기 저용 상태를 제공합니다.
7.6 프로토타입 패턴
자바스크립트 생태계에서는 클래스처럼 따로 정의되는 것이 아니라, 이미 존재하는 다른 객체를 복재하여 새로운 객체를 만들어냅니다.
프로토타입 패턴의 장점은 다른 언어의 기능을 따라하지 않고, 자바스크립트만이 가진 고유의 방식으로 작업할 수 있다는 것입니다.
7.7 팩토리 패턴
팩토리 패턴은 객체를 생성하는 생성 패턴의 하나입니다. 다른 패턴과 달리 생성자가 필요로하지 않지만, 필요한 타입의 팩토리 객체를 생성하는 다른 방법을 제공합니다.
class Animal {
constructor({name, color}) {
this.name = name;
this.color = color;
}
toString() {
return `Animal name is ${this.name}, color is ${this.color}`;
}
}
// 팩토리 클래스
class AnimalFactory {
createAnimal(type, props) {
switch(type) {
case 'dog':
return new Animal({...props, type: 'dog'});
case 'cat':
return new Animal({...props, type: 'cat'});
default:
throw new Error('지원하지 않는 동물 타입입니다.');
}
}
}
// 사용 예시
const factory = new AnimalFactory();
const dog = factory.createAnimal('dog', { name: '멍멍이', color: '갈색' });
const cat = factory.createAnimal('cat', { name: '야옹이', color: '흰색' });
7.7.1 팩토리 패턴을 사용하면 좋은 상황
팩토리 패턴은 다음과 같은 상황에서 특히 유용합니다.
객체 생성 과정이 복잡할 때
동적인 요소나 애플리케이션 구조에 깊게 의존하는 경우
객체 생성에 필요한 설정이나 의존성이 많은 경우
객체 생성 로직을 한 곳에서 관리하고 싶을 때
7.7.2 팩토리 패턴을 사용하면 안 되는 상황
잘못된 상황에 팩토리 패턴을 사용하면 애플리케이션의 복잡도가 크게 증가할 수 있습니다. 라이브러리나 프레임워크를 설계 목표가 아니라면 생성자를 사용하는 것이 좋습니다.
7.7.3 추상 팩토리 패턴
같은 목표를 가진 각각의 팩토리들을 하나의 그룹으로 캡슐화하는 패턴입니다. 객체가 어떻게 생성되는지에 대해 알 필요 없이 객체를 사용할 수 있게 해줍니다.
// 추상 팩토리 인터페이스
class GUIFactory {
createButton() {
throw new Error('createButton() must be implemented');
}
createCheckbox() {
throw new Error('createCheckbox() must be implemented');
}
}
// Windows 스타일 팩토리
class WindowsFactory extends GUIFactory {
createButton() {
return new WindowsButton();
}
createCheckbox() {
return new WindowsCheckbox();
}
}
// Mac 스타일 팩토리
class MacFactory extends GUIFactory {
createButton() {
return new MacButton();
}
createCheckbox() {
return new MacCheckbox();
}
}
// 클라이언트 코드
class Application {
constructor(factory) {
this.factory = factory;
}
createUI() {
const button = this.factory.createButton();
const checkbox = this.factory.createCheckbox();
return { button, checkbox };
}
}
// 사용 예시
const windowsApp = new Application(new WindowsFactory());
const macApp = new Application(new MacFactory());
7.8 구조 패턴
구조 패턴은 클래스와 객체의 구성을 다룹니다. 상속의 개념을 통해 인터페이스와 객체를 구성하여 새로운 기능을 추가할 수 있는 것처럼 말입니다.
7.9 퍼사드 패턴
퍼사드란 실제 모습을 숨기고 꾸며낸 겉모습만을 세상에 드러내는 것을 뜻합니다. 여기서 퍼사드 패턴이란 심층적인 복잡성을 숨기고, 사용하기 편리한 높은 수준의 인터페이스를 제공하는 패턴입니다.
jQuery와 같은 자바스크립트 라이브러리에서 흔히 볼 수 있는 패턴입니다.
// jQuery에서 퍼사드 패턴을 사용하는 예제
$(el).css
$(el).animate()
7.10 믹스인 패턴
C++나 Lisp 같은 전통적인 프로그래밍 언어에서 믹스인은 서브클래스가 상속받아 기능을 재사용 할 수 있도록 하는 클래스입니다.
7.11 서브클래싱
부모클래스를 확장하는 자식 클래스를 서브 클래스라고 합니다.
서브클래싱이란 부모 클래스 객체에서 속성을 상속받아 새로운 객체를 만드는 것을 말합니다.
class SuperCar extends Car {
constructor(name, power){
super(name);
this.power = power
}
}
const superCar = new SuperCar('람보르기니', 200);
console.log(superCar); // power를 가지고 있는 Car를 호출합니다.
7.12 믹스인
믹스인은 최소한의 복잡성으로 객체의 기능을 빌리거나 상속할 수 있게 해줍니다. 다른 여러 클래스를 아울러 쉽게 공유할 수 있는 속성과 메서드를 가진 클래스입니다.