본문 바로가기
Js

observer 패턴

by 은지:) 2025. 4. 27.
728x90
반응형

 

class Subject {
  constructor(){
    this.observerList = new Set([])
  }
  subscribe(observer){
    this.observerList.add(observer)
  }
  unSubscribe(observer){
    this.observerList.delete(observer)
  }
  notify(data){
    this.observerList.forEach((e)=>e.update(data))
  }
}

class Observer {
  constructor(key){
    this.key = key;
  }
  update(data){
    console.log(this.key,":  ",data)
  }
}


const book = new Subject();

const authorEunji = new Observer("eunji")
const authorEunji2 = new Observer("eunji2")

book.subscribe(authorEunji)
book.subscribe(authorEunji2)

book.notify("몽땅 적용하기")

 

 

구독하는 옵저버 패턴...

리액트에 이미 내장되어 있다

 

state나 props가 변하면

그걸 관찰하고 있는 컴포넌트가 반응함

 

변경될 수 있는 state props가 subject()이고

컴포넌트는 이 state 와 props를 관찰하고 있는 observer임

 

 

흉내내기

 

// Subject (상태 관리자)
class StateManager {
  constructor(initialValue) {
    this.value = initialValue;
    this.listeners = new Set();
  }

  subscribe(listener) {
    this.listeners.add(listener);
    // 처음에도 값을 바로 내려줌
    listener(this.value);
  }

  unsubscribe(listener) {
    this.listeners.delete(listener);
  }

  setValue(newValue) {
    if (this.value !== newValue) {
      this.value = newValue;
      this.listeners.forEach(listener => listener(this.value));
    }
  }
}

// "컴포넌트" 흉내
function createComponent(renderFn) {
  const element = document.createElement('div');
  renderFn(element);
  return element;
}

// 실제 사용
const countState = new StateManager(0);

function CounterComponent(root) {
  function render(value) {
    root.innerHTML = `<h1>Count: ${value}</h1>`;
  }

  countState.subscribe(render);
}

// 버튼 만들어서 이벤트
function ButtonComponent(root) {
  const button = document.createElement('button');
  button.innerText = 'Increment';
  button.onclick = () => {
    countState.setValue(countState.value + 1);
  };
  root.appendChild(button);
}

// 앱 시작
const app = document.getElementById('app');

const counter = createComponent(CounterComponent);
const button = createComponent(ButtonComponent);

app.appendChild(counter);
app.appendChild(button);
728x90
반응형

'Js' 카테고리의 다른 글

for문 안에 setTimeout 걸면 어떻게 동작할까  (2) 2024.11.04
실행 컨텍스트와 호이스팅  (0) 2024.11.03

댓글