디자인 패턴(싱글톤, 팩토리, 전략, 옵저버) - 자바스크립트

따봉도치 개발자·2023년 8월 24일
0

1. 싱글톤 패턴을 아세요?

싱글톤 패턴(Singleton Pattern)은 객체 지향 프로그래밍에서 디자인 패턴 중 하나로, 어떤 클래스가 오직 하나의 인스턴스만을 가지도록 보장하는 패턴이다. 이 패턴을 사용하면 특정 클래스의 인스턴스가 오직 하나만 존재하게 되며, 이를 통해 전역적인 상태나 리소스를 공유하거나 중복 생성을 방지할 수 있다. 보통 데이터베이스 연결 모듈에 많이 사용된다.


1-1. 모듈 패턴 싱글톤

const singleton = (function() {
  let instance;

  function createInstance() {
    // 실제 인스턴스 생성 로직
    return { /* ... */ };
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    },
  };
})();

const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();

console.log(instance1 === instance2); // true

1-2. 클래스 기반 싱글톤

class Singleton {
  constructor() {
    if (!Singleton.instance) {
      Singleton.instance = this;
    }
    return Singleton.instance;
  }
}

const instance1 = new Singleton();
const instance2 = new Singleton();

console.log(instance1 === instance2); // true

이러한 싱글톤 패턴을 사용하면 하나의 인스턴스만을 유지함으로써, 공유 상태를 효율적으로 관리하거나 중복 생성을 방지할 수 있다. 그러나 너무 많은 곳에서 공유 상태를 사용하거나 객체 의존성을 컨트롤하기 어려워질 수 있으며, 코드가 복잡해질 수 있다. 또한, 미리 생성된 하나의 인스턴스를 기반으로 구현하는 패턴이므로 TDD(Test Driven Development)를 할 때 주로 단위 테스트를 진행하는데 각 테스트 마다 독립적인 인스턴스를 만들기 어렵다.

2. 팩토리 패턴을 아세요?

상속 관계에 있는 두 클래스에서 상위 클래스가 뼈대 역할을 하고 하위 클래스에서 객체 생성에 관한 내용을 결정하는 패턴이다.

위 예시를 보면 라떼, 아메리카노, 우유 레시피는 하위 클래스가 컨베이어 벨트를 통해 상위 클래스에 전달되고, 이 상위 클래스는 레시피들을 토대로 라떼, 아메리카노, 우유를 생산하는 공정이라고 생각하면 된다.

class Latte {
    constructor() {
        this.name = "라떼"
    }
}
class Espresso {
    constructor() {
        this.name = "에소프레쏘"
    }
}
class LatteFactory {
    static createCoffe() {
        return new Latte()
    }
}
class EspressoFactory {
  static createCoffe() {
    return new Espresso();
  }
}
const factoryList = { LatteFactory, EspressoFactory }

class CoffeeFactory {
    static createCoffee(type) {
        const factory = factoryList[type]
        return factory.createCoffe()
    }
}
const main = () => {
    // 라떼 주문
    const coffee = CoffeeFactory.createCoffee
}

3. 전략 패턴을 아세요?

전략 패턴(Strategy Pattern)은 직접 수정하지 않고 알고리즘 또는 동작을 캡슐화하여 이를 서로 교환 가능한 형태로 만들어준다. 주로 여러 알고리즘이 있을 때, 이들 중 하나만 선택해서 사용할 경우 필요하고, 동일한 문제를 다양한 방법으로 해결할 때 사용한다.

4. 옵저버 패턴을 아세요?

옵저버 패턴(Observer Pattern)은 객체들 사이의 일대다 관계를 정의하여 한 객체의 상태 변화가 다른 객체들에게 자동으로 알려지고 갱신될 수 있도록 하는 패턴이다. 이 패턴을 사용하면 한 객체의 변경이 발생했을 때, 해당 객체에 의존하는 다른 객체들에게 변경 사항을 알리고 업데이트할 수 있다.

자바스크립트에서 프록시 객체를 이용한 옵저버 패턴 사용하기

일단 프록시 객체에 대해서 먼저 알아보자. 프록시(proxy)는 객체를 감싸고, 해당 객체에 접근하려는 시도를 가로채거나 수정하는 기능을 제공하는 객체이다. 이를 통해 객체의 동작을 변경하거나 제어할 수 있다. 대리자라고 생각하면 될 거 같다.

const targetObject = {
 name: 'John',
 age: 30,
};
const handler = {
 get(target, property) {
   console.log(`Accessing property: ${property}`);
   return target[property];
 },
};
const proxy = new Proxy(targetObject, handler);
console.log(proxy.name); // 결과: "Accessing property: name"와 함께 "John" 출력
console.log(proxy.age); // 결과: "Accessing property: age"와 함께 30 출력

위 예시에서 targetObject는 원본 객체이다. handler 객체는 프록시 동작을 정의한 객체입니다. get 메서드를 정의하여 프록시가 속성에 접근할 때 동작을 지정할 수 있다. get 메서드는 두 개의 인자를 받는다.
target: 프록시로 감싸진 원본 객체(targetObject)property: 접근하려는 속성 이름
new Proxy(target, handler)를 사용하여 targetObject를 감싸는 프록시를 생성.
프록시는 원본 객체의 동작을 변경하거나 확장할 수 있다.
proxy.nameproxy.age는 프록시를 통해 원본 객체의 속성에 접근하는 코드이고, 이 때 get 메서드가 실행되며, property에 해당하는 속성에 접근하는 동작을 수행하게된다. console.log를 사용하여 "Accessing property: name""Accessing property: age"가 각각 출력되고, 실제 속성 값이 반환 받게 된다.

프록시 객체를 이용한 옵저버 패턴을 구현해보자.

    const proxy = new Proxy(target, {
        set(obj, prop, value) {
            if (value !== obj[prop]) {
                const prev = obj[prop]
                obj[prop] = value
                callback(`${prop}가 [${prev}] >> [${value}]로 변경되었읍니다.`)
            }
            return true
        }
    })
    return proxy
}

const a = {
    "수빈" : "커플"
}
const b = createReactiveObject(a, console.log)
b.수빈 = "솔로"
b.수빈 = "커플"
// 수빈이 [커플] >> [솔로]로 변경
profile
Explain Like I'm 5

0개의 댓글