Observer

μ˜΅μ €λ²„ νŒ¨ν„΄μ΄λž€ νŠΉμ • 객체의 μƒνƒœλ₯Ό μ—¬λŸ¬ observer 듀이 κ΅¬λ…ν•˜μ—¬ 객체의 λ³€ν™”κ°€ μžˆμ„ λ•Œλ§ˆλ‹€ μ˜΅μ €λ²„ λ“€μ—κ²Œ μ•Œλ €μ£ΌλŠ” νŒ¨ν„΄μ„ λ§ν•œλ‹€. 쑰금 더 μžμ„Ένžˆ λ§ν•˜μžλ©΄, 객체에 λ³€ν™”κ°€ λ°œμƒν•˜κ²Œ 되면 ν•΄λ‹Ή 객체λ₯Ό κ΅¬λ…ν•˜κ³  μžˆλŠ” μ˜΅μ €λ²„λ“€μ—κ²Œ μƒνƒœκ°€ λ°”λ€Œμ—ˆλ‹€λŠ” μ•Œλ¦Όμ„ 보내 μƒνƒœλ₯Ό κ°±μ‹ ν•˜λ„λ‘ ν•˜κ²Œ ν•˜λŠ” 것이닀.

μš°λ¦¬κ°€ μΈμŠ€νƒ€κ·Έλž¨ 같은 snsλ₯Ό μ‚¬μš©ν•˜λ©΄μ„œ λ‚΄κ°€ νŒ”λ‘œμš°ν•œ μ‚¬λžŒμ˜ κ²Œμ‹œλ¬Όμ΄ μ—…λ°μ΄νŠΈ 될 λ•Œλ§ˆλ‹€ μ•Œλ¦ΌμœΌλ‘œ μ•Œλ €μ£ΌλŠ” 것을 μƒκ°ν•˜λ©΄ νŽΈν•  λ“― ν•˜λ‹€. 보톡 μΌλŒ€μΌ, μΌλŒ€λ‹€μ˜ 관계λ₯Ό κ°€μ§„λ‹€.

μ˜΅μ €λ²„ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ§€ μ•Šμ„ 경우, νŠΉμ • 객체에 λ³€ν™”κ°€ μΌμ–΄λ‚¬λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄ 주기적으둜 확인을 ν•΄μ£Όμ–΄μ•Ό ν•˜λŠ”λ°, 이것을 λ°”λ‘œ Polling 이라고 ν•œλ‹€. 이 경우, 풀링을 ν•˜λŠ” λ¦¬μ†ŒμŠ€μ˜ μΆ”κ°€ 및 풀링 사이에 μ΄λ²€νŠΈκ°€ λ°œμƒν•˜κ²Œ 될 경우, ν•΄λ‹Ή 이벀트λ₯Ό 캐치 ν•˜μ§€ λͺ»ν•˜λŠ” 상황이 λ°œμƒν•  μˆ˜λ„ μžˆλ‹€.

이제 μ˜΅μ €λ²„ νŒ¨ν„΄μ˜ μž‘λ™ λ‘œμ§μƒμ—μ„œ ν•„μš”ν•œ λ‘κ°œμ˜ 객체λ₯Ό μ‚΄νŽ΄λ³΄μž.

Subject (Object)

μƒνƒœ λ³€ν™”μ˜ 주체 객체이닀. 이 κ°μ²΄μ—λŠ” 객체λ₯Ό κ΅¬λ…ν•˜κ³  μžˆλŠ” μ˜΅μ €λ²„λ“€μ˜ λ¦¬μŠ€νŠΈμ™€ μ—¬λŸ¬ λ©”μ„œλ“œλ“€μ΄ ν¬ν•¨λ˜μ–΄ μžˆλ‹€.

  • subscribe : 객체에 μ˜΅μ €λ²„λ₯Ό λ“±λ‘ν•˜λŠ” λ©”μ„œλ“œ

  • notify : updateκ°€ μ‹€ν–‰λ˜μ—ˆμ„λ•Œ, μ˜΅μ €λ²„λ“€μ—κ²Œ μ•Œλ €μ£ΌλŠ” λ©”μ„œλ“œ

νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜κΈ° μœ„ν•΄ ν•„μˆ˜μ μΈ 두 κ°€μ§€μ˜ λ©”μ„œλ“œ 이닀. SubjectλŠ” μƒνƒœμ˜ λ³€ν™”κ°€ μΌμ–΄λ‚˜κ²Œ 되면 μ˜΅μ €λ²„ λ¦¬μŠ€νŠΈμ— μžˆλŠ” μ˜΅μ €λ²„λ“€μ—κ²Œ notify λ©”μ„œλ“œλ₯Ό ν†΅ν•˜μ—¬ 이 객체 μƒνƒœκ°€ λ³€ν–ˆλ‹€λŠ” 것을 μ•Œλ €μ€€λ‹€.

κ°„λ‹¨ν•œ κ΅¬ν˜„ μ˜ˆμ‹œλ₯Ό 보도둝 ν•˜μž.

interface ISubject {
  subscribe(observer: Observer): void;
  remove(observer: Observer): void;
  notify(): void;
}

class Subject implements ISubject {
  // μ˜΅μ €λ²„ 리슀트
  private observers: Observer[] = [];
  private state: any;

  // μ˜΅μ €λ²„λ₯Ό λ“±λ‘ν•˜λŠ” subscribe λ©”μ„œλ“œ
  subscribe(observer: Observer): void {
    this.observers.push(observer);
  }
  // λ“±λ‘λœ μ˜΅μ €λ²„λ₯Ό μ œκ±°ν•˜λŠ” remove λ©”μ„œλ“œ
  remove(observer: Observer): void {
    const index = this.observers.indexOf(observer);
    if (index > -1) {
      this.observers.splice(index, 1);
    }
  }
  // μ˜΅μ €λ²„λ“€μ—κ²Œ μƒνƒœλ³€ν™”λ₯Ό μ•Œλ €μ£ΌλŠ” notify λ©”μ„œλ“œ
  notify(): void {
    for (const observer of this.observers) {
      observer.update(this.state);
    }
  }
  setState(state: any): void {
    this.state = state;
    this.notifyObservers();
  }

  getState(): any {
    return this.state;
  }
}

Observer

Subject의 μƒνƒœλ₯Ό κ΅¬λ…ν•˜κ³  μžˆλŠ” μ˜΅μ €λ²„ 객체이닀. Subject와 μœ μ‚¬ν•˜κ²Œ 내뢀에 λ©”μ„œλ“œλ₯Ό ν¬ν•¨ν•˜κ³  μžˆλŠ”λ°, Subject 의 μƒνƒœ λ³€ν™”κ°€ μΌμ–΄λ‚˜κ²Œ λ˜μ–΄ μ•Œλ¦Όμ„ λ°›μ•˜μ„λ•Œ 싀행될 update λ©”μ„œλ“œκ°€ λ°”λ‘œ 그것이닀. μΌλŒ€λ‹€μ˜ 관계λ₯Ό κ°€μ§„ μ˜΅μ €λ²„ νŒ¨ν„΄μ˜ νŠΉμ„±μƒ, μ—¬λŸ¬ μ˜΅μ €λ²„κ°€ ν•„μš”ν•˜κ²Œ 되면 클래슀λ₯Ό λ§Œλ“€μ–΄ μƒμ†ν•˜μ—¬ μ‚¬μš©ν•˜κ²Œλ” λ§Œλ“ λ‹€.

κ°„λ‹¨ν•œ κ΅¬ν˜„κ³Ό μ–΄λ–€ μ‹μœΌλ‘œ μ‚¬μš© ν•˜λŠ”μ§€μ— λŒ€ν•œ μ˜ˆμ‹œλ₯Ό μ‚΄νŽ΄λ³΄μž.

interface IObserver {
  update(data: any): void;
}

class Observer implements IObserver {
  private id: number;

  constructor(id: number) {
    this.id = id;
  }

  update(data: any): void {
    console.log(`Observer ${this.id} received data: ${data}`);
  }
}

const subject = new Subject();

const observer1 = new Observer(1);
const observer2 = new Observer(2);

subject.subscribe(observer1);
subject.subscribe(observer2);

subject.setState("Hello Observers!");

subject.remove(observer1);

subject.setState("Only observer2 should receive this");

Last updated